The React Fact that will Change your Mindset

THE FACT: ReactDOM.render is not destructive

If you repeatedly call ReactDOM.render on a component, passing in different props each time, then React doesn’t tear down that component and start from scratch. React updates the component’s props while maintaining its internal state. Before showing how this fact will change your mindset, let’s demonstrate its veracity with the aid of an example.

The example shows a Timer component that increments every second. The colour of the number displayed alternates between red and blue every other second. The Timer stores the seconds count in state and the display colour in props. To toggle the colour, we run a setTimeout every two seconds that calls ReactDOM.render passing the new colour prop to the Timer. You can see that ReactDOM.render is not destructive because the count, held in state, doesn’t reset when we change the colour:

You Don’t Need the React Router

Let’s modify the Timer example so that, instead of changing the display colour inside of a setTimeout, we pass the colour in the URL. We’ll add ‘red’ and ‘blue’ Hyperlinks that set the respective colour in the URL. Whenever the hash changes, we’ll call ReactDOM.render on the Timer component passing in the colour prop:

window.addEventListener('hashchange', function(){
  ReactDOM.render(
    <Timer colour={location.hash} />,
    document.getElementById('container')
  );
};

Without even trying to, we’ve created a basic router. We’ve been led to believe that updating components when the URL changes is so difficult that only the React Router can do it. Think of the complexity the React Router would introduce to the Timer example. By owning the Timer component, the React Router would prevent us from passing in the colour prop. Realising that ReactDOM.render isn’t destructive is like casting a magic spell that makes the React Router disappear. Taking back ownership of your components will change your mindset.

Giving up the React Router doesn’t mean giving up the ability to share UI across pages because React supports templates. A React template is any component that hosts a placeholder DOM element. We render this template when our app loads and target all subsequent ReactDOM.render calls at the template’s placeholder. Below is an example of an App template with a ‘content’ placeholder:

var App = () => (
  <div>
    <h1>Example<h1>
    <div id="content"></div>
  <div>
);

ReactDOM.render(
  <App />,
  document.getElementById('container')
);

If we add this App template to the Timer example then, whenever the URL changes, we ReactDOM.render the Timer component into the ‘content’ placeholder of the template instead of the ‘container’ element in the HTML:

ReactDOM.render(
  <Timer colour={location.hash} />,
  document.getElementById('content')
);

You’ve nothing to fear on the performance front because rendering your own templates and components is at least as fast the React Router doing it for us:

Try the Navigation Router

I’m not suggesting you don’t need a router. Just that you use one that embraces, rather than competes with, React. One that doesn’t render your components and that focuses instead on what React doesn’t do. I recommend my Navigation router. Its data-first approach to routing complements React’s top-down render as you can see in the Timer example below:

Advertisements

2 thoughts on “The React Fact that will Change your Mindset

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s