React 17 is our stepping stone

ยท 2 mins read ยท ย React

Did you ever want to upgrade a rather big React application of yours? I bet you did. So what was your plan?

At first, you were excited but then you realized that this is way more challenging than you expected in the first place. Why? Because you had to upgrade the whole codebase in one big step following an "all-or-nothing" approach.

This strategy works eventually but for large or legacy codebases it might be tough, time-consuming and a bit risky.

# Why React 17?

React 17 will make this way easier since it will let us use React trees managed by one major version inside a tree managed by a different one. That way we will be able to upgrade parts of the codebase to React 18 while the rest will stay in React 17.

So React 17 prepares the ground for the upcoming major releases without adding any new developer-facing features so we can upgrade easily to it.

Its main goal is to help us push forward and upgrade gradually old and large React applications to the upcoming major versions without leaving anyone behind. That is why it is called a "stepping stone" release.

How cool and useful is that!!!

# What was the main issue React 17 had to tackle?

The main problem React 17 had to deal with so we can have component trees that use different major versions, is the way that the library itself handles events.

React since its early days uses event delegation. This means that an event handler attached to a DOM element inline is actually attached to a parent container. React uses the document itself as the container.

An extremely naive example is the following. An inline click handler like the one below:

<button onClick={() => alert('I got clicked')}>Click me</button>

It is handled actually under the hood like:

document.addEventListener('click', function(e) {
  if (e.target?.nodeName === 'BUTTON') {
    alert('I got clicked');
  }
});

The example above is not super-accurate but you get the picture regarding events and the way they are attached to the document.

This pattern might be a bit fragile when we have multiple React component trees that use different major versions. Think about this example.

Imagine that a nested tree wants to block the events' propagation for some reason. Unfortunately, the blocked events will still reach the outer tree because of events' delegation to the document. We said that all events are attached to it, right? As you get, all this is getting difficult to handle by using different React versions.

The solution was to replace document with the root Node into which every React tree is attached. That way things are gettings simpler since we don't have all events across all trees attached to one common container (the document) anymore.

const rootNode = document.getElementById('root');

ReactDOM.render(<App />, rootNode);

This means that from React 17 and on, we will have rootNode.addEventListener and not document.addEventListener for events handling.

React 17 is our stepping stone

Thanks to this change, we can embed React way easier into apps built with other technologies like jQuery etc which is extremely beneficial especially for legacy apps.

# Other changes

As we said before, there are no actual developer-facing features but there are 2-3 changes we should mention here:

  • Event polling is dropped so we don't need to use e.presist() anymore. The presist method will be available just to make upgrades easier so it won't do anything
  • useEffect cleanup runs asynchronously after the screen has been updated. If we need to run this synchronously we should better use useLayoutEffect instead
  • memo and forwardRef will throw consistent errors when returning undefined by mistake
  • We will be able to debug our applications a bit easier when an error is thrown because of the updated component stacks mechanism that stitches them together from the regular native JavaScript stacks. This will lets us get the fully symbolicated React component stack traces in a production environment

# Conclusion

React 17 is a stepping stone release that will help us move easier to the upcoming major versions of the library. It doesn't introduce any breaking changes so we can easily upgrade to it.

Right now it is in Release Candidate so nothing stops us from getting our hands dirty and start playing with it.

We can install it with:

yarn add react@17.0.0-rc.0 react-dom@17.0.0-rc.0

Remember, this is not 100% stable yet for production apps. Cheers!!

You can read the official post if you need to go deeper regarding React 17

Newsletter

Get notified about latest posts and updates once a week!!