Implementing React Hooks: useState

Joe C Gomez
6 min readJan 11, 2021

Documentation: https://reactjs.org/docs/hooks-intro.html

GitHub: https://github.com/JoeG21/medium-ex/blob/master/react-hooks-useState/src/App.js

So after learning hooks, I understand why developers prefer them over Class Components. It’s much easier to main the state and of course update it. It’s nothing too hard to understand but can be somewhat confusing for first timers. I would recommend going back to old projects of yours and refactoring them into functional components.

There’s 2 things you need to know before incorporating hooks into your application. The 1st being, you can only use hooks in functional components. This is because there’s already ways to set state in a class components like the constructor() and state = {}.

The 2nd being, your hooks must be called in the exact same order in every component render. All this means is that you cannot set state inside any conditionals, functions, or loops. Because if you set state inside of a if statement, it may or may not run causing it to change the order. And hooks must be at the top level.

For our example we are going to being using the useState hook and making our application function like this. You absolutely do not have to add CSS, you can remove all <div> tags and it’ll function the same way. It just did it for my own benefit!

First, we have to import useState into our component. After that we can declared useState, which is a function that always return an array with 2 values. The first value is going to be the current state (color) and the second value is the function that lets us update the current state (setColor). We can name these 2 values anything we want, it’s just best practice to name the second value “set<the 1st value>” for readability reasons. Then we set that array to equal useState and anything that is pass into our parameters is going to be our default state, which in this case is “?”.

In order to call state into our return, we simply put the 1st value of our array which we named “color” (Line 27) into our JSX. At this point we should have some buttons that are labeled “Red”, “Green”, and “Blue” with a printed out question mark. Now in order to change the state when a user click on the buttons, we just need to add event listeners like what we would do in a class components and add logic to those functions.

Like I mention, useState returns 2 values. This is where the second value comes into play the update function (setColor). We declared (Line 8, 12, & 16) them and pass in what we went the state to be updated to in the parameters. Every time we call our update function (setColor) it’s going to re-render our component with the new value for our state (color), just like what would happen with any other set state inside of a class component. When you update the state your component re-renders!

However this is the incorrect way to update the state based on the previous state. Just like class component, there’s a second version of updating the value which allows you to pass in a function.

This function takes an argument, which we can name anything to represent the previous state value (“prevState” is what I named it). Use the arrow function expression to represent what you want the state to be updated to.

Now that we have our application working with hooks, there’s more to know about useState

useState has 2 ways to pass in the state, the first one is the hardcoded version like in our example (Line 5). This will always render the component every single time you run the function. By doing so, this could slow down the performance of the application if it’s something complex like Fibonacci.

The other way is the functional version. Using the functional version of useState will only run the function one time when the component renders. This is great for complex computations. We can prove this by putting a console.log into our code and inspecting the page to look at our console.

Lastly, useState works differently when dealing with objects.

I’m adding a new state named “phrase” with a default state value of “Hello World” (Line 5), and invoking the values we declared on line 6 & 7 into our JSX on line 36 & 38.

As you can see, whenever we change colors our “Hello World” completely disappear. It doesn’t merge our old state unlike what a class component would atomically do. Everything in the state is being overridden whatever we update the state because of what we are passing down into the update function (setState in line 12, 18, & 24).

Now if you do want to use an object, we just have use the spread operator (…) to maintain the previous state.

On line 12, 18, and 24 the “…prevState” are the values inside our useState (color: ‘?’, phrase: ‘Hello World’), then we are just updating our color.

It’s important to notice that if you do use an object inside of your stat that when you up the object you need to make sure you update it with all the old values as well because they don’t get merged together automatically!

The reason why the automatic merging does not happen is because in general when you are using hooks to set state, it’s always best to have multiple state hooks. It defects the whole purpose of using hooks, because you can breakdown and isolate a single piece of state and have it inside its own hook. Compare to keeping track of multiple, completely unrelated, states inside one hook.

Generally you should watch out for deeply nested objects in React state. This could cause unexpected behavior, so it’s best to avoid using objects when setting state with hooks.

That’s pretty much it, now you can use useState in your applications! I wish I learned this much sooner because it makes state 10x easier and readable.

For fun I wrote the first example in a class component which has 863 characters, compare to the functional component that has 767!

Thank you for reading and I would love feedback! You can of course checkout my GitHub for the code and the official documentation!

Documentation: https://reactjs.org/docs/hooks-intro.html

GitHub: https://github.com/JoeG21/medium-ex/blob/master/react-hooks-useState/src/App.js

--

--

Joe C Gomez

Find some time to do something! 🧠 Flatiron Alumni 🏛