Creating React components using only ES5 features
Tags: react, javascript, beginners
Published: 2018-07-25 12:47:02

---
title: Creating React components using only ES5 features
published: true
description: a few examples showing that you can use React without JSX or setting up a build step.
tags: react, javascript, beginners
---

This post will be just a friendly reminder that React "It's just javascript". It's okay to use it without a build step. It's okay to use it to create a tiny interactive component. And you don't have to use ES6+ if you don't want to.

### Quick recap on the createElement function
React exposes a function called createElement which is the bread and butter of every component. JSX is actually syntactic sugar that translates to `React.createElement` calls. It looks something like this: 

```javascript
React.createElement(
    'tagName',       // HTML tag name or a custom component 
    props,           // HTML attributes, custom properties, events, etc...
    children         // a string or a list of components or almost anything
);
```
### Stateless components
This types of component only take `props` and returns a React element. They don't manage their own state and don't have lifecycle methods. They're perfect to present data that comes from other sources. Without any build step it could look like this:

```javascript
function Welcome(props) {
    return React.createElement('div', null, 'Hello, ' + props.name);
}

ReactDOM.render(Welcome({ name: 'world' }), container);
```
### Class components
These components can manage their own internal state and have lifecycle methods. Here is the thing, in ES5 we can't use the `class` keyword to create a component, instead will have to mimic that behavior.

The first thing we will need to take care of is the inheritance. Normally you would use `class MyComponent extends React.Component` to do that. We're going to take another road, we will "force" the inheritance by overriding the `prototype` object of our component with the one from `React.Component`, like so:

```javascript
function MyComponent(props) {
    React.Component.constructor.call(this);

    // ... code
}

MyComponent.prototype = Object.create(React.Component.prototype);
```

What's different here from our stateless component is that we call `React.Component` constructor with the context of our custom component, and that we make sure that the prototype is the one from `React.Component`. With this in place now our component can use the lifecycle methods and the setState method.

### Example code

Now with our new found knowledge we can create some components without setting up a build step, or worrying too much about browser support. Lets do a simple timer: 

```javascript
var container   = document.getElementById('app');

// h is short for hyperscript and it makes everything a little bit easier
var h           = React.createElement;

// This is how we inherit methods like setState from React.Component
Timer.prototype = Object.create(React.Component.prototype);

function Timer(props) {
  React.Component.constructor.call(this);
  var self = this;
  
  self.state = { seconds: 0 };

  self.tick = function() {
    self.setState(function(prevState) {
      return { seconds: prevState.seconds + 1 };
    });
  };
  
  self.componentDidMount = function() {
    self.interval = setInterval(self.tick, 1000);
  };
  
  self.componentWillUnmount = function() {
     clearInterval(self.interval);
  };
  
  self.render = function() {
    return h('div', null, 'seconds: ', self.state.seconds);
  }
}

ReactDOM.render(h(Timer), container);
```

Notice here that I'm assigning the `this` context in a `self` variable to avoid using the `bind` method of the Function prototype. And I'm using it everywhere just for consistency sake, though I believe is only necessary in `self.tick` where I would lose the `this` context when using it in `setInterval`.

### One last thing

One thing people don't notice at first is that the children of an element are also parameters. You can pass a component, a string, an object or a function. At the end of the day `children` is a prop.

Let me show you something.
{% codepen https://codepen.io/VonHeikemen/pen/LBLZOe %}

### Conclusion

This works, and is not that bad. This just shows you that you can use React with the good old script tags to embed it in any site. Another thing that shows is that React Component are function calls, you can do anything that you can think of. Really, you can do anything, including shooting your self in the foot so be careful.

### Other resources
[Todo List example](https://codepen.io/VonHeikemen/pen/YjQWYv)
[Timer example](https://codepen.io/VonHeikemen/pen/GBEmBM)
[React without a build step](https://medium.com/@alexkrolick/writing-react-components-for-3rd-party-embedding-50331c18e26)
[React is just JavaScript](https://medium.com/yld-engineering-blog/react-is-just-javascript-88600553269c)

---

Thank you for reading. If you find this article useful and want to support my efforts, [buy me a coffee ☕](https://www.buymeacoffee.com/vonheikemen).

[![buy me a coffee](https://res.cloudinary.com/vonheikemen/image/upload/v1618466522/buy-me-coffee_ah0uzh.png)](https://www.buymeacoffee.com/vonheikemen)