Author avatar

Dustin McQuay

Just Plain React

Dustin McQuay

  • Jan 10, 2019
  • 6 Min read
  • Jan 10, 2019
  • 6 Min read


Many packages are commonly used with React to handle things like state management and routing. When you are new to React, it is overwhelming to try to learn all of this at once. Let's build a simple React app without any extras.

Hello World without JSX

Most people use JSX with React, but that requires Babel, which in turn means we need something like Webpack. If we don't use JSX, then we don't have to worry about any of that. Here's a JSX-free example to get us started.

1<!DOCTYPE html>
3  <head>
4    <meta charset="UTF-8" />
5    <title>Hello World</title>
6    <script src=""></script>
7    <script src=""></script>
8  </head>
9  <body>
10    <div id="root"></div>
11    <script type="text/javascript">
12      var e = React.createElement;
13      ReactDOM.render(
14        e('h1', null, 'Hello, world!'),
15        document.getElementById('root')
16      );
17    </script>
18  </body>

The first argument to React.createElement is the element type (or your custom component, which we'll see later). The second is properties you can pass into that element (usually referred to as props). The third is child elements. In this case, we'll just display "Hello, world!" here, but we could put another element or component here or even a list of them.

Paste this into an html file and open it in your browser.

In case you're curious, JSX is syntax sugar so that you can write <h1>Hello, world!</h1> instead of React.createElement('h1', null, 'Hello, world!'). See React Without JSX for more info.


React applications can be split up into Components. Here's the beginning of a TODO app that demonstrates components.

1var e = React.createElement;
3function TodoItem() {
4  return e("li", null, "Todo Item");
7function TodoApp() {
8  return e("div", null, [
9    e("h1", { key: "title" }, "To Do List"),
10    e("ul", { key: "todos" }, [
11      e(TodoItem, { key: "item1" }),
12      e(TodoItem, { key: "item2" })
13    ])
14  ]);
17ReactDOM.render(e(TodoApp), document.getElementById("root"));

What's with the keys props?

A key is a unique string you must provide when creating lists of elements. You can read more about react keys, but I recommend you skip it for now.

Class-style Components without ES6

To get state and lifecycle hooks, you must use the class style for creating components. Most examples use ES6 classes for this, but that would mean we need Babel once again. To avoid this, pull in create-react-class with a little help from like this: <script src="[email protected]/create-react-class.js"></script>. This will expose a function called createReactClass which we can use to create stateful components. Here's an example:

1var TodoItem = createReactApp({
2  render: function() {
3    return e("li", null, "Todo Item");
4  }

This is a silly example, but we'll make better use of it in the next section.

Check out the React Without ES6 docs for more info on this subject.

Plain React State

Some kind of state library, such as Redux, is often pulled into React apps and it's a whole new layer to understand. Don't assume your app needs this. React's built in component state will suffice in many cases. It is recommended that you store your state in a top level component and pass that down to child components via props. Here's a simple TODO app that demonstrates this.

1var e = React.createElement;
3function TodoItem(props) {
4  return e("li", null, props.text);
7var TodoApp = createReactClass({
8  getInitialState: function() {
9    return { items: [], text: "" };
10  },
12  handleEditInput: function(evt) {
13    this.setState({ text: });
14  },
16  handleSubmit: function(evt) {
17    evt.preventDefault();
18    if (!this.state.text.length) return;
19    this.setState(function(prevState) {
20      return {
21        items: prevState.items.concat({
22          id: Math.random() + "",
23          text: prevState.text
24        }),
25        text: ""
26      };
27    });
28  },
30  render: function() {
31    return e("div", null, [
32      e("h1", { key: "title" }, "To Do List"),
33      e("input", {
34        key: "input",
35        type: "text",
36        value: this.state.text,
37        onChange: this.handleEditInput
38      }),
39      e(
40        "button",
41        { key: "add-todo-btn", onClick: this.handleSubmit },
42        "Add ToDo"
43      ),
44      e(
45        "ul",
46        { key: "todos" },
47 =>
48          e(TodoItem, { key:, text: item.text })
49        )
50      )
51    ]);
52  }
55ReactDOM.render(e(TodoApp), document.getElementById("root"));

What's Next?

You can now build a reasonably functional app without having to learn all about JSX, Webpack, Babel, Redux, etc. You may find that you want to add these things in, but you don't have to.

You are now equipped to take one of the following next steps:

  1. Build an app following the above patterns.
  2. Learn one more building block at a time, such as JSX, with a solid understanding of React to build upon.
  3. Try out something like create-react-app or NEXT.js if you want all the extras, but don't want to set them all up manually.