What's New in React 16.9

What's New in React 16.9

  • 1131

As we prepare for React v17, the React core team continues to make incremental changes and recently released React 16.9.0. This release builds on previous versions with a number of deprecations, new features and bug fixes.

As we prepare for React v17, the React core team continues to make incremental changes and recently released React 16.9.0. This release builds on previous versions with a number of deprecations, new features and bug fixes.

In this article we’ll be looking at new changes introduced in React 16.9.

Renaming Unsafe Lifecycle Methods

One of the biggest driving forces behind React 17 is asynchronous rendering which aims to improve both the user and developer experience. To allow asynchronous rendering, there has to be a change in the component lifecycle and this involves deprecation of some lifecycle methods which were introduced without async rendering in mind.

One of the biggest driving forces behind React 17 is asynchronous rendering

To prepare for these deprecations these lifecycle methods will be renamed in React 16.0 as follows:

  • componentWillMount → UNSAFE_componentWillMount
  • componentWillReceiveProps → UNSAFE_componentWillReceiveProps
  • componentWillUpdate → UNSAFE_componentWillUpdate

Now your code will look like:

class App extends Component {

  UNSAFE_componentWillMount() {
    // ewwwww
  }

}

This is a nudge to get all React devs to stop using these methods.

React 16.9 does not contain breaking changes, and the old names continue to work in this release. But you will now see a warning when using any of the old names. These warnings provide better alternatives to these lifecycle methods.

Essential Reading: Learn React from Scratch! (2019 Edition)

Easily Renaming UNSAFE Methods

To allow easy renaming for projects where one may not have adequate time to migrate to the recommended lifecycle methods, the React team recommended a script from codemod that automates this process.

cd your_project
npx react-codemod rename-unsafe-lifecycles

This will rename all the affected lifecycle methods to prepare for the migration to React 17.

Deprecating JavaScript: URLs

URLs starting with javascript: are a dangerous attack surface because it’s easy to accidentally include unsanitized output in a tag like <a href> and create a security vulnerabilities such as making the app more vulnerable to XSS attacks.

const userProfile = {
  website: "javascript: alert('you got hacked')",
};

// This will now warn:
<a href={userProfile.website}>Profile</a>

In React 16.9**,** this pattern continues to work, but it will log a warning. If you use javascript: URLs for logic, try to use React event handlers instead. It is also important to note that in future releases, javascript: urls will throw an error in React.

Deprecating “Factory” Components

Introduced prior to ES6 classes with Babel, React’s "factory” component returned an object with a render method as shown below.

function FactoryComponent() {
  return { render() { return <div />; } }
}

Despite not being the same as a regular functional component, this method looks very similar and may cause some confusion. It is also slightly slower and larger than necessary while also being very rarely used by developers. As a result it will be deprecated in React 16.9 and warnings will show up wherever this pattern is used.

If you rely on it, adding FactoryComponent.prototype = React.Component.prototype can serve as a workaround. However, it is advisable it to either a class or a function component as they are more efficient.

Async act() for Testing

Introduced in React 16.8, [act()](https://reactjs.org/docs/test-utils.html#act) is a testing utility to help you write tests that better match the browser behaviour. However, act() didn’t initially support asynchronous functions in React 16.8.

As of React 16.9 , act may now be used with async functions in the following format:

await act(async () => {
  // ...
});

This solves the remaining cases where you couldn’t use act() before, such as when the state update was inside an asynchronous function. As a result, you should be able to fix all the remaining act() warnings in your tests now.

For more information about testing patterns with act() you can check out the testing recipes.

Performance Measurements with<react.profiler></react.profiler>

The React profiler for devtools was introduced in React 16.5 to enable measurement of the performance of React Components in order to allow developers to pinpoint areas where their applications can be better optimised.

In React 16.9 a more programmatic method of measuring performance through the <React.Profiler /> component.

The <Profiler> measures the frequency at which a React application renders and what the cost of each render is. Its helps identify parts of an application that are slow and may benefit from optimizations like memoization. It can be added anywhere in a React component tree to measure the cost of rendering that part of the tree.

It requires two props: an id (string) that identifies which part of the tree you are measuring incase you are using multiple profilers and an onRender callback which React calls any time a component within the tree “commits” an update as shown, this callback aggregates render cost.

render(
  <Profiler id="application" onRender={onRenderCallback}>
    <App>
      <Navigation {...props} />
      <Main {...props} />
    </App>
  </Profiler>
);

It is important to note the that the Profiler adds some overhead and should be disabled for the production build of the application.

Notable Bugfixes

This release contains a few other notable improvements fixing a number of known issues from the previous releases:

  • A crash when calling findDOMNode() inside a <Suspense> tree has been fixed.
  • A memory leak caused by retaining deleted subtrees has been fixed too.
  • An infinite loop caused by setState in useEffect now logs an error. (This is similar to the error you see when you call setState in componentDidUpdate in a class that may cause a component to keep re-rendering.)

Conclusion

React has a very exciting roadmap as it continues to grow and improve with both users and developers in mind. Asynchronous rendering is a big deal as it will greatly improves the React experience for everyone involved by creating an environment where fast and responsive applications can easily be built.