Skip to content

A React Tutorial for p5 Programmers

Atul Varma edited this page Apr 14, 2016 · 20 revisions

This is a React tutorial for people who are already familiar with p5.js. A basic conceptual familiarity with the Document Object Model is also highly recommended: if you're unfamiliar with it, consider reading p5's Beyond the canvas tutorial.

This tutorial is a riff on p5's Get Started tutorial, because it's both familiar and fun.

Your First (React) Sketch

Start out with the following HTML file:

<!DOCTYPE html>
<meta charset="utf-8">
<title>React Sketch</title>
<div id="sketch"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.1/react-dom.js"></script>
<script src="react-sketch.js"></script>

And the following JS file:

// react-sketch.js

var Sketch = React.createClass({
  render: function() {
    return React.createElement('svg', {
      width: '640',
      height: '480'
    }, React.createElement('circle', {
      cx: '50',
      cy: '50',
      r: '40',
      stroke: 'black',
      fill: 'white'
    }));
  }
});

ReactDOM.render(
  React.createElement(Sketch),
  document.getElementById('sketch')
);

Loading this page should give you a stationary circle:

Let's examine the code you just wrote.

In the HTML, you're loading two libraries, React and ReactDOM. There actually used to be just one library, and the distinction between the two isn't actually completely obvious. You're welcome to read an explanation on StackOverflow, but it's totally fine if you skip it.

In the JS, you're doing a number of things:

  1. You're calling a function called React.createClass() and assigning its return value to a variable called Sketch. Here you're creating something called a React component, and it's the fundamental building block of React-powered programs. Components are nicely self-contained chunks of functionality that you can hook together to build awesome things.

  2. You're calling a function called ReactDOM.render() and passing a DOM node as its second argument. This basically "injects" your React program into the web page.

The Sketch component has only one method called render(), and it's actually a little bit like the draw() method of a p5 sketch, with a few notable exceptions:

  • By default, it's not called 60 times per second. In fact, it's only called whenever the state of the component changes. State is just data which uniquely determines how the component should display itself--more on that later.

  • It generally doesn't call many functions itself, but rather returns a React Element which represents what the DOM controlled by React should look like.

Our render() function is calling React.createElement(), which is the primary mechanism through which React Elements are created. In our case, we're creating an <svg> element with width and height attributes; the single child of this element is an SVG <circle> element with cx, cy, r, stroke, and fill attributes. Its HTML representation looks like this:

<svg width="640" height="480">
  <circle cx="50" cy="50" r="40" stroke="black" fill="white" />
</svg>

JSX

It turns out that React rendering code is so peppered with calls to React.createElement() that its creators made some syntactic sugar for it called JSX. In JSX, the following is literally equivalent to our Sketch component's render() method:

function render() {
  return (
    <svg width="640" height="480">
      <circle cx="50" cy="50" r="40" stroke="black" fill="white"/>
    </svg>
  );
}

You can read more about JSX in React's documentation on JSX Syntax. JSX isn't required to use React, but it tends to make React code read more concisely.

Transpiling Ugh

So JSX is cool and all, but because it's not part of the JavaScript standard or anything, browser's won't understand it by default. So we'll need to use something called a transpiler to convert our JSX into JS.

We don't just want a transpiler for the JSX benefits, though; we'll also eventually want to take advantage of the newest version of JavaScript, ES2015, and it isn't fully supported across all major browsers yet. So our transpiler will help solve that problem too.

Right now we're going to use a transpiler called Babel, which works in the browser. To use it, we'll first rename react-sketch.js to react-sketch.jsx and then change out HTML a bit:

<!DOCTYPE html>
<meta charset="utf-8">
<title>React Sketch</title>
<div id="sketch"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.1/react-dom.js"></script>
<script type="text/babel" src="react-sketch.jsx"></script>

The browser won't load our react-sketch.jsx file itself, because it doesn't know what to do with a script of type text/babel. Instead, Babel will find that tag, manually load our content itself, transpile it, and then tell the browser to run it. Cool! Sort of.

By now your head might be spinning a bit from all this new tooling and stuff. The field is actually moving so fast that some programmers are saying JavaScript development is crazy, which is a fair point!

But, some of these new technologies reflect really interesting ideas that can enlighten us even if we decide not to use them, so I'm going to try to spend the rest of this tutorial focusing on the "big picture" rather than the nitty-gritty details, which you can read up on elsewhere.

Clone this wiki locally