As of React 16.8 our beloved functional components were repurposed to be more than just presentational functions that returned JSX. Before its upgrade functional components were not able to manage state nor have access to life cycle methods. But now all of that has changed and in the following example I will illustrate how your typical class component would like as a new and improved functional component using React Hooks.
Below is a typical class component that renders a list of names after an axios request. Recall that componentDidMount runs once AFTER the component has first mounted. Therefore this is the perfect spot to make your API calls as you do not want to continuously make those calls necessarily.
With React Hooks functional components can now do the same. The code snippet below is a result of rewriting the class component illustrated above using React Hooks namely useState and useEffect.
Let’s break down this piece by piece. But first, notice that we have to import useState and useEffect in order to use these hooks.
This functional component can now manage state using useState. useState takes in initial state as it’s only parameter and returns two arguments. It returns the current state, in this case contacts , and a function that updates state, in this example setContacts.
useEffect is a function that takes in a callback function and an array of dependencies as parameters — more on this second parameter later. In this example, our callback function invokes our fetchContacts function which ultimately ‘effects’ the state of our component by invoking setContacts with the information received from our API.
The flow is as follows:
- The component first mounts.
- Then useEffect is in run and once inside we can run fetchContacts.
- fetchContacts then makes its axios request. Once we have received that data we pass it into setContacts. Recall that setContacts is a function that updates state so once invoked with data from the API call, it will cause a re-render as state has now changed.
This API call occurs once because the dependencies array (aka the second parameter of our useEffect) is an empty array. When the second parameter of a useEffect function is an empty array it essentially functions as componentDidMount. If the functional component was dependent on other pieces of state or props then it would be included in the dependencies array. Once included in the dependencies array, useEffect can detect those changes and cause components to re-render accordingly.
In summary, useState and useEffect parallels state/setState and componentDidMount (when your dependencies array is empty) from class components respectively. With that in mind, I hope I was able to shed some insight into React Hooks. Of course there is so much more React Hooks can offer and I would encourage you to read React docs here for more examples. Thank you and until next time!