I’ve spent the last couple of weeks learning React in my coding bootcamp and have ignored Hooks for the sake of building a solid foundation in the basic concepts.
You might say I was a straight-laced kid who followed the rules and grasped function versus class components and how state can be stored in class components along with accessing lifecycle methods, while props and state can be passed down to children components regardless of component type. And knowing when and how to use this. (Yes, there is a lot more to React than this, but I’m painting a picture of whimsy for my upcoming analogy).
But it was high time I ditched school to learn about Hooks (okay, studied it over the weekend), and it was exhilarating and also felt like this at first:
Hooks were introduced in February 2019 with React 16.8, allowing us to use state and other React features without writing a class component. Wait, what? State without a class component? React offers a few built-in Hooks as well as the ability to customize your own Hooks.
React documentation stresses that there are no plans to remove classes from React and that Hooks work side-by-side with existing code so you can adopt Hooks gradually.
I'll be touching on the following two Hooks:
By calling the
useState Hook, aka the State Hook, it declares a new state variable that gives it the same capabilities that
this.state provides in a class.
Below is how we would store state in a class component:
And here I use the State Hook to store state in a function component:
To break down
useState further in my example, particularly this line of code:
const [clicked, updateClicked] = useState(false);
I am calling my state variable
updateClicked is the function that updates
clicked. These are similar to
this.setState, respectively, but you get them both in a packaged pair on the
To set the initial value of the state, we pass
useState an argument. Since I want the value of
clicked to start off as false, I pass in false here. Another differing factor from classes is that the state here does not have to be an object, but can be just a number or string.
When a user clicks on my button,
updateClicked will update the state and React will then re-render my Hello component, passing the new
clicked value along and changing the text of my button. Pretty neat.
useEffect Hook, aka the Effect Hook, lets us perform side effects in components and is similar to lifecycle methods in classes. Side effects examples include data fetching and manually changing the DOM. Pro tip: the useEffect Hook is like componentDidMount, componentDidUpdate, and componentWillUnmount rolled into one.
Using this Hook tells React that our component needs to do something further after render, and by default it will run after the first render and after every update. Having
useEffect inside the component gives it access to the state variable or any props right from the effect without needing a special API to read it, as it’s already in the function scope.
Something to keep in mind is that there are two types of side effects in React components: those that do not require cleanup (run additional code and then can forget about that code), and those that do require cleanup (unsetting any mutated changes). I'll only be discussing side effects that do not require cleanup so please do check out the awesome React documentation for more information.
Side effects that don't require cleanup typically go into
componentDidUpdate in class components, like the example below. As I want to fetch my user when the component mounts and fetch again if the userId prop has been changed, I would need to have both lifecycle methods call the same method.
Below, I've re-written it using the Effect Hook. You’ll notice that the code isn’t duplicated with separate method calls because by default React will call
useEffect after any DOM updates. To prevent unnecessary fetches in my example (or any side effect activity), you can pass in a second argument to
useEffect of an array of values that the effect depends on. That way, it will only conditionally fire if the props have changed.
Hooks are a great addition to making your components more reusable and composable. Even though class components are not going away, by all means, play more Hook(y)!