When the results of the “State of JavaScript 2018” survey were published, React emerged as the winner for the front-end framework category, with a 91 percent satisfaction rate and more than 16,000 users:
React is today’s most popular library for building user interfaces, and in this post, we will look at notable new features, deprecations, and bug fixes that have been added to version 16.9.
React Profiler was first added to React DevTools in v16.5. This feature measures each component that’s rendered in order to find the “cost” of rendering, so that you can identify performance bottlenecks in React application faster.
In order to use it, you can open React’s DevTools, run a record, render some React components, and then stop the recording.
The Profiler is useful but a bit cumbersome. You have to start the record and stop it, and then inspect parts of the record that seems to have a high load time. That’s why we now have the <React.Profiler>
component, which can be used to gather performance metrics in a programmatic way.
The component will require two properties: an id
property and an onRender
property. It will fire anytime a component within the tree re-renders. Here is some example code:
import React, {Profiler} from 'react'; import ReactDOM from 'react-dom'; ReactDOM.render( <Profiler id="MyAwesomeApp" onRender={onRender}> <Router> <App /> </Router> </Profiler>, document.getElementById("root") ); function onRender( id, phase, actualDuration, baseDuration, startTime, commitTime, interactions ) { console.log(id) console.log(phase) console.log(actualDuration) console.log(baseDuration) console.log(startTime) console.log(commitTime) console.log(interactions) }
And here is the result in the console:
While the Profiler from the DevTools records all of your React app, with the <React.Profiler>
component, you can isolate and record only the parts of the tree that require more attention. Also, it’s disabled automatically in production build, so you don’t need to remove it after measuring.
For more details on the Profiler component and explanations for its parameters, check out the official documentation here.
act()
functionReact introduced a testing utility called act()
to help developers create UI tests. When writing UI tests, there are tasks like rendering, user interaction events like a click, or data fetching that can be considered “units” of interaction with your React application.
Due to the asynchronous nature of JavaScript, React might actually skip some task and assert the test immediately without waiting until the tasks are done.
React provides a helper called act()
that will ensure all updates related to these “units” have been processed and applied to the DOM before you make any assertions.
But a problem with act()
was that it could only support synchronous functions, so if you had async functions inside your act()
, you were out of luck.
Fortunately, it has now been improved and you can use async/await with act()
:
await act(async () => { // ... });
This will help you ensure asynchronous updates are done before assertion. Here’s a great tutorial on how you might use act()
.
The React team had already announced this change almost a year ago. In this version, the unsafe lifecycle methods are finally getting renamed:
componentWillMount
→ UNSAFE_componentWillMount
componentWillReceiveProps
→ UNSAFE_componentWillReceiveProps
componentWillUpdate
→ UNSAFE_componentWillUpdate
Don’t worry, unsafe doesn’t mean your app is more prone to being hacked — it simply reminds you that code inside these lifecycles are more likely to have bugs in future versions of React. Check out the details here.
The method name without UNSAFE_
prefix will continue to work in this version, but they are about to be removed completely later, when React version 17 is released. If you open your developer console, you will receive a warning about this:
These prefixed method names are meant to help components with problematic patterns stand out during code review and debugging sessions. It is commonly not recommended to use these methods, so you can discourage your team from using them even more the Strict Mode.
And if your app actually uses a lot of these methods, you can use this codemod to refactor it faster than manually editing them yourself:
cd your_project npx react-codemod rename-unsafe-lifecycles
It will start an interactive prompt to select which files you want to rename.
javascript:
URLs on schedule for removalUsing javascript:
inside the href
attribute was popular way back when, but today, it is an obsolete practice that can open security holes in your app. It’s easy to accidentally include unsanitized outputs. For example:
const userProfile = { website: "javascript: alert('you got hacked')", }; <a href={userProfile.website}>Profile</a>
The code above will cause an error in React 17, and if you want to run a script when a link is clicked, you need to use the React onClick
event handler and a button element that is styled as a link. It is safe and just as easy to implement:
awesomeFunction = () => console.log("Here is javascript: URL alternative!"); // the button below used Bootstrap styling... <button className="btn btn-link" onClick={this.awesomeFunction}>Profile</button>
FactoryComponent
patternThis is a rather obscure code pattern that was introduced by the React team before compiling classes with Babel became popular. It’s a component that returns an object with a render
method:
function FactoryComponent() { return { render() { return <div />; } } }
The syntax looks pretty bad, and since Babel has become the standard compiler for React apps, this component pattern is no longer needed. Supporting it causes React to be slightly larger and slower than necessary. It will be completely removed in a future major release.
If your app happens to use this pattern, you can use FactoryComponent.prototype = React.Component.prototype
to keep it working, but it’s far better to just convert the code to a function or a class.
An infinite loop caused by setState
in useEffect
will now log an error, similar to the error you see when you call setState
in componentDidUpdate
in a class component. Here is some sample code:
function App() { const [counter, setCounter] = React.useState(0); React.useEffect(() => { setCounter(counter + 1); }) return <h1>Watch out infinite loop in the console!</h1> }
Since there is no second argument that this effect depends on for update, it will run forever until you close the browser window.
findDOMNode()
is calledThe <React.Suspense>
component is used for lazy-loading components that are not needed in the initial render. But since version 16.7, many developers started receiving the error Invariant Violation: Unable to find node on an unmounted component
when using it.
After inspection, developers figured out the error is caused by calling ReactDOM.findDOMNode()
inside Suspense. The crash is now fixed in this release, but if you’re still interested, here is a codesandbox to test the error. Just randomly click on the menu until the error appears.
You might not use findDomNode()
directly, but this function is actually used in many libraries, like Semantic UI and Ant Design. So you might just unintentionally trigger this bug if you don’t update your React library!
To update your application, simply run:
npm install --save react@^16.9.0 react-dom@^16.9.0
Or, if you’re using Yarn:
yarn add react@^16.9.0 react-dom@^16.9.0
Happy hacking!
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowBuild scalable admin dashboards with Filament and Laravel using Form Builder, Notifications, and Actions for clean, interactive panels.
Break down the parts of a URL and explore APIs for working with them in JavaScript, parsing them, building query strings, checking their validity, etc.
In this guide, explore lazy loading and error loading as two techniques for fetching data in React apps.
Deno is a popular JavaScript runtime, and it recently launched version 2.0 with several new features, bug fixes, and improvements […]