React.js, one of the most popular JavaScript libraries around, has released version 16.8.0, which includes official support for Hooks.
React now has over 100 releases, more than 130,000 GitHub stars, 2 million-plus projects, and a host of dedicated community members making life easier for developers building amazing user interfaces.
Hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks let you use state and other React features without writing a class, as they do not work inside classes. A simple example of the use state hook looks like this:
import React, { useState } from 'react'; function Example() { // Declare a new state variable, which we'll call "count" const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
In this article, Hooks will not be treated in earnest, but instead you will be shown the motivation behind Hooks, demystifying Hooks, and their advantages.
React’s core team hinted at a few problems people tend to face over time while building applications with React. Most of them seem unconnected at first but are all valid:
By default, there was previously no clear way to attach attach a reusable behavior to a React component. You have patterns like using render props and higher-order components to try and hack this, of course, but you end up changing the component’s structure any time they are used.
This almost always leads to clumsy code presentation and, by inheritance, causes the code to become borderline illegible. A typical React application will contain wrappers of components containing providers, consumers, HOCs, and many other concepts that are mostly abstract.
DevTools and linting can help break most of it down, but React needs a kind of root-level concept for sharing stateful logic. Hooks fit in perfectly here, and you can extract stateful logic from a component so it can be tested independently and reused. You can learn more about building your own Hooks here.
A good illustration is the use of lifecycle methods: you know how logic can be passed from one method to another, or how only computations can be done in a method only to be used in another method.
In the process of consuming these methods, a lot of unrelated logic, from little things like console.log
messages to larger things like event listeners, can be introduced. This makes it more likely that the next developer to work on the code — or even the original author — will become confused at some point.
Imagine maintaining components that started out simple but grew into an unmanageable mess of stateful logic, side effects, and, of course, bugs. In many cases, it’s not possible to break these components into smaller ones because the stateful logic is all over the place, making unit testing hard.
Hooks also helps to solve this exact problem because you can split one component into smaller functions based on what pieces are related to what.
Remember how unintuitive it was for you to understand classes in React when you first started to use it? A lot of developers just starting out still do not fully grasp how this
works in JavaScript; it does not help that it differs from language to language.
Other good examples are the differences between and when to use what arguments for functional and class components in React, which further shows just how confusing classes can sometimes be.
It gets worse: even machines (i.e., compilers) find classes confusing most times. Take minifiers, for example. The React team reports that classes do not minify well and sometimes even make hot reloading flaky and unreliable. Hooks as a solution provides a platform to let you use React features, but without classes this time.
To get started, you have to install the new version 16.8 with your favorite registry. To install React 16 with Yarn, run:
yarn add react@^16.8.0 react-dom@^16.8.0
To install React 16 with npm, run:
npm install --save react@^16.8.0 react-dom@^16.8.0
UMD builds of React are also accessible through a CDN:
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
Refer to the documentation for detailed installation instructions.
Now that you have been inspired to try out React Hooks, here are some resources to get you started on trying it them:
getSnapshotBeforeUpdate
and componentDidCatch
lifecycle methods yet.useRedux()
or useRouter()
that will not require wrapper components.React now has an ESLint plugin that enforces the rules of Hooks to avoid bugs and makes you, the developer, follow the convention. First, the plugin flags any function that starts with “use” and a capital letter following it as a Hook. These rules are:
The popular create-react-app boilerplate already integrates this plugin in all the React applications bootstrapped with it.
Yes! Starting with 16.8.0, React includes a stable implementation of React Hooks for React DOM, React DOM Server, React Test Renderer, and React Shallow Renderer. React Native will support Hooks in the 0.59 release.
The React team added a new API called ReactTestUtils.act()
in this release. It ensures that the behavior in your tests matches what happens in the browser more closely. It is recommended to wrap any code rendering and triggering updates to your components into act()
calls. Testing libraries can also wrap their APIs with it.
For example, the counter-example from this page can be tested like this:
import React from 'react'; import ReactDOM from 'react-dom'; import { act } from 'react-dom/test-utils'; import Counter from './Counter'; let container; beforeEach(() => { container = document.createElement('div'); document.body.appendChild(container); }); afterEach(() => { document.body.removeChild(container); container = null; }); it('can render and update a counter', () => { // Test first render and effect act(() => { ReactDOM.render(<Counter />, container); }); const button = container.querySelector('button'); const label = container.querySelector('p'); expect(label.textContent).toBe('You clicked 0 times'); expect(document.title).toBe('You clicked 0 times'); // Test second render and effect act(() => { button.dispatchEvent(new MouseEvent('click', {bubbles: true})); }); expect(label.textContent).toBe('You clicked 1 times'); expect(document.title).toBe('You clicked 1 times'); });
The calls to act()
will also flush the effects inside of them. If you need to test a custom Hook, you can do so by creating a component in your test and using your Hook from it.
Also, to reduce boilerplate code, it is recommended to use react-testing-library
, which is designed to encourage writing tests that use your components as the end users do. You can view the complete changelog for this new version here.
You have now been introduced to the new version of React.js, which shipped with stable support for React Hooks. The motivation that led to the adoption of this new way of approaching writing React code has also been illustrated. Give Hooks a try today — 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>
Would you be interested in joining LogRocket's developer community?
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 nowDesign React Native UIs that look great on any device by using adaptive layouts, responsive scaling, and platform-specific tools.
Angular’s two-way data binding has evolved with signals, offering improved performance, simpler syntax, and better type inference.
Fix sticky positioning issues in CSS, from missing offsets to overflow conflicts in flex, grid, and container height constraints.
From basic syntax and advanced techniques to practical applications and error handling, here’s how to use node-cron.