This tutorial is out of date and no longer maintained.
React version 16.6 is out and it comes packed with some useful new features that are very much worth getting excited about. It’s a minor release with major features focused on performance optimization. The main new features include:
StrictMode
Let’s take a look into what each of these features adds to React.
React.memo()
is the functional component solution to React.PureComponent
as used in class components. It’s a higher order component that is wrapped around functional components to create memoized components.
We’ve written up a full tutorial on React.memo() here: React.memo() for Functional Components Rendering Control
What are memoized components? To understand this, we’ll have to look at the definition of memoization, which is an optimization technique that stores the results of expensive function calls and returns these cached results in case similar inputs are provided. Hence the name memo.
The result is a component that only re-renders when it’s props change, acting kind of like shouldComponentUpdate()
.
Memo is applied by wrapping a component inside React.memo()
as shown below:
const MemoizedComponent = React.memo(function MyComponent(props) {
// only re-renders if props change
});
// for arrow functions
const OtherMemoized = React.memo(props => {
return <div> Memoized Component </div>
}
You may also wrap an existing component to memoize it.
const MyComponent = props => <div> This is memorable!! </div>
const Memoized = React.memo(MyComponent)
Note that server side rendering for memo is still pending.
To dive deeper into memo check out this article here which looks at more use cases and gives an example.
Code-splitting allows us to lazy-load our imports, which means we only import them when they are being used hence increasing the overall speed of our applications. These are referred to as dynamic imports.
React.lazy()
allows us to render dynamic imports as regular components. It takes a function that must call a dynamic import()
. This must return a Promise which resolves to a module with a default
export containing a React component.
Without React.lazy in < React 16.6:
import OtherComponent from './OtherComponent';
function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}
With React.lazy in React 16.6:
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}
Notice all we have to do is update the import statement! Very easy to implement and similar to how react-loadable does it.
In case MyComponent
renders before our dynamic import, we should show some fallback content to act as a placeholder as we wait for it to load, such as a loader. This can be achieved using the higher order Suspense
component.
Suspense takes a prop, fallback
, which accepts React elements to be rendered while loading dynamic imports. And a single Suspense component can handle several dynamic imports.
If we have an app that is lazy loading components as shown below, if either of the components (OtherComponent or AnotherComponent) fails to load, this will break the app.
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));
function MyComponent() {
return (
<div>
<section>
<OtherComponent />
<AnotherComponent />
</section>
</div>
);
}
We can prevent this by introducing Suspense to show a fallback loader as long as either of these components have not yet loaded as shown below.
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<section>
<OtherComponent />
<AnotherComponent />
</section>
</Suspense>
</div>
);
}
The official Context API was introduced in React 16.3 and in a bid to ease usage in class components, contextType
has now been added to classes. This property can be assigned a Context object created by React.createContext()
. It lets you consume the value of that Context object in your class using this.context
and this can be referenced in any lifecycle method.
class ScotchClass extends React.Component {
componentDidMount() {
let value = this.context;
// perform a side-effect at mount using the value of MyContext
}
componentDidUpdate() {
let value = this.context;
// ...
}
componentWillUnmount() {
let value = this.context;
// ...
}
render() {
let value = this.context;
// render something based on the value of MyContext
}
}
ScotchClass.contextType = ScotchContext;
Important to note, this method only allows you to consume one context.
Introduced in React 16.3, error boundaries allow us to catch errors early and render fallback UI and prevent the app from crashing. However, the API hadn’t provided a method of handling errors that occur before rendering. In comes the static method getDerivedStateFromError()
. This lifecycle is invoked after an error has been thrown by a descendant component. It receives the error that was thrown as a parameter and should return a value to update state providing a method to handle the error.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
getDerivedStateFromError()
is called during the “render” phase, so side-effects are not permitted. For those use cases, use componentDidCatch()
instead.
Yet another feature introduced in React 16.3, StrictMode is a higher order component that identifies potential problems in an application and provides warnings for them. In React 16.6 two more API’s have been added to the list of deprecated APIs and will fire warnings in StrictMode. These are:
ReactDOM.findDOMNode() - This API is often misunderstood and most uses of it are unnecessary. It can also be surprisingly slow in React 16.
Legacy Context using contextTypes and getChildContext - Legacy context makes React slightly slower and bigger than it needs to be. Upgrading to the new Context API is encouraged and the addition of contextType
aims to make this easier.
React 16.6 has some pretty big additions for a minor update and aims to help developers create high performance applications that are stable, light and fast. It shows a significant step forward for React as the library continues to grow. It’s exciting to see what else the future holds for React. Read more about this release on the React blog.
Even with all the great things 16.6 has, it’s looking like 16.7 is going to be even greater!
https://twitter.com/sophiebits/status/1055127361367076864
See you then!
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!