DEV Community

Katherine Kelly
Katherine Kelly

Posted on • Updated on

Playing Hooky with React

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:

nick jonas gif

What Are Hooks?

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: useState and useEffect.

useState Hook

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 clicked, and updateClicked is the function that updates clicked. These are similar to this.state.clicked and this.setState, respectively, but you get them both in a packaged pair on the useState return.

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

The 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 componentDidMount and 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)!

React Hooks

Discussion (0)