As you probably know, from version 16.8 React introduces the new Hooks API which seems to be recently blowing frontend minds across the globe. Let’s have a closer look at them and decide whether it’s the time to rewrite your current app.
No, it’s not the time to create your app from scratch. Unless it’s unmaintainable piece of software and there are other serious reasons to do so. Besides that, React Hooks work great along with your current code.
But, from the beginning. What are those Hooks and what is the benefit of using them?
Hooks are a new feature proposal that lets you use state and other React features without writing a class.
As the official documentation says they main purpose is to give you access to the component’s state and the ability to call its lifecycle callbacks without creating a class component. It’s a great news cause the main reason of using class components were exactly those two things. Reasons why you should favour function components than class components are subject for another article so let’s leave it there for now and come back to hooks.
React comes with two main built-in hooks that you may find useful: useEffect and useState.
useState gives you access to the component’s local state just how you did with using this.state and this.setState in class components. It takes in only one argument – initial value – and returns a pair: a variable and a function to update it. Basic usage looks like this:
const [number, setNumber] = useState(0);
Note that value doesn’t have to be an object. It can be anything, and in example above it is a numeric value. We call useState with zero to set its initial value and in exchange we got a variable holding the value and a callback function. Easy, right? We’ll see a real app example in a moment.
The second hook – useEffect – is useful to perform tasks similar to the ones you did in componentDidMount, componentWillMount or componentDidUpdate like calling an API, manipulating DOM or resetting a timer.
Let’s take a closer look at useState and see how it works on a real app.
Here’s a fairly simple web application built on top of create-react-app and bulma. It displays a search box where you can input book title and after the form is submitted it calls OpenLibrary API and after successful call it displays the results. Obviously during the call the spinner show up to indicate that search is in progress.
And here’s the code:
The code above uses component’s state to store data fetched from the API: array of books found, count of total result, loading indicator and a query from search input.
In the onSearch method we’re performing an API call followed by storing the result in the state by calling setState on the component.
There’s also another method called onQueryChange which handles storing query typed into the search input.
Both of the functions are manipulating the state through this.setState method and accessing its values by using this.state. Let’s see how we can refactor it to get rid of the class component, make it a function component and use useState hook instead of the internal component’s state.
In the above example App is a function component, actually an arrow function, which in its scope has two other functions: onSearch and onQueryChange. They’re performing exactly the same job like they did in the previous example, but instead we’re taking advantage of the React latest useState hook to store and modify the state:
const [isFetching, setIsFetching] = useState(false);
const [books, setBooks] = useState();
const [numFound, setNumFound] = useState(0);
const [query, setQuery] = useState('');
Note how we use the useState function. We pass in a default value, which will be assigned to the corresponding state variable when it’s initialised. In exchange we got an array containing our variable, through which we can access its value and a function to change it.
In latest version (3.6) React DevTools browser extension supports hooks too! So you can inspect the app and see your hooks working in real life – isn’t that awesome?
👋 Hey hooks alpha testers! ⚛️ DevTools support just landed in v3.6! Enjoy! pic.twitter.com/QTyk1UvsYn— Brian Vaughn (@brian_d_vaughn) 14 January 2019
I hope you guys enjoy playing with new React features same as I do. Full working example of the app used in this article is available on Github. Happy coding!