
React 16.8 – Captain Hook is here
React 16.8 was shipped on Feb 06, 2019, bringing with it the Hook feature that everyone was waiting for. It was a version behind schedule, as React 16.7 was going to be the one.
Ok maybe not that Hook!!!
After over 6 months from its introduction in React Conf 2018, Facebook development team finally released Hook feature into a stable version release. This feature helps our functional components having most class components features, including having internal state, context, and even lifecycle methods!!!
Tl; dr;
React 16.8 shipped with the stable Hook feature, allowing us to use state, context and lifecycles inside functional components. Hooks resolves 3 problems that React had: Wrapper hell, Huge components, and Confusing classes. Facebook team advises that we should start using Hooks in our new React features for a consistent code style as well as reducing duplication.
Hooks overview
Hook is released without any breaking changes. It is a brand new feature and does not interfere with existing features.
Class components are hard to test, especially lifecycle methods. Using hooks can decouple the lifecycle functions and make them easy to test.
There are multiple kind of hooks: State Hook, Context Hook, Effect Hook, or build your own Custom Hooks.
Facebook has released a good documentation to Hooks here. In this post, we will just discuss about what I think is important to mention outside their documentation.
State Hook
More details here.
// what you see in their documents can be confusing const [count, setCount] = useState(0); // what it is actually is const [state, setState] = useState(initialState);
Best thing about `useState` is that you can have multiple state control in your component. Traditionally, we only have 1 state object in a class component. But with this approach, we can have as many state objects as we need.
Context Hook
More details here.
// returns the value of the context const value = useContext(SomeContext);
Nothing special here, calling `useContext` will return the value of that context, and instead of having to consume the context, we just need to use that value.
// traditional way of using context render() { return ( <Context.Consumer> {(value) => (<MyComponent value={value} />)} </ContextConsumer> ); } // with useContext const OtherComponent = () => { const value = useContext(Context); return (<MyComponent value={value} />); };
Effect Hook
More details here.
Basically just an implementation of lifecycle methods. Every extra tasks that a component does besides rendering DOM elements are side effects, and should use effect Hook to execute them. I’ll use the same example in the documentation.
import React, { useState, useEffect } from 'react'; // class example class Example extends React.Component { state = { count: 0, }; componentDidMount() { // set title on mount document.title = `You clicked ${this.state.count} times`; } componentDidUpdate() { // set title on update document.title = `You clicked ${this.state.count} times`; } setCount = (count) => { this.setState({ coount }); }; render() { const { count } = this.state; return ( <div> <p>You clicked {count} times</p> <button onClick={() => this.setCount(count + 1)}> Click me </button> </div> ); } } // functional example function Example() { const [count, setCount] = useState(0); // Similar to componentDidMount and componentDidUpdate: useEffect(() => { // Update the document title using the browser API document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
We can clearly see that the code is duplicated on `componentDidMount()` and `componentDidUpdate()` lifecycle functions. Effect Hook helps us removing that duplication.
Custom Hooks
More details here.
Something to remember here, React will consider a function to be a custom Hook if it starts with use
.
useTitleUpdate = (count) => { document.title = `You clicked ${count} times`; }; // usage const MyComponent = () => { const [count, setCount] = useState(0); useTitleUpdate(count); return (...); };
Important thing to remember
– Hooks are only declared at top level, meaning we CANNOT declare Hooks in the following examples.
// loops for (let i = 0; i < 10; i++) { const [value, setState] = useState(1); ... } // conditions if (x === 1) { const [value, setState] = useState(1); ... } // nested functions const MyComponent = () => { const handleSave = () => { const [value, setState] = useState(1); ... }; };
There is a linter plugin to prevent developers doing this.
Other releases
Along with Hooks, React 16.8 also releases bug fixes and test utilities to test Hooks feature.
Quick recap
Hooks feature certainly offers a way to make React code more readable and efficient. However, we do not need to change the existing class components to use Hooks, as suggested in their talk at React Conference 2018. Both of them are doing the same thing under the hood, it’s just the implementation that is different.
2 Responses
[…] used libraries, frameworks, and tools, JavaScript-based technologies like Node.js, AngularJS, React top the […]
[…] 16.9 does NOT contain any breaking changes, so we can upgrade from 16.8 safely. It contains a programmatic profiler so developers can measure the performance of the […]