The useState() Hook: Practical Guide

The useState() Hook: Practical Guide

Do you know what is the difference between a class component and a function component in React?

In this practical guide I will try to explain how the component's state is managed in both components after the second got on steroids!

Stateful and Stateless components

In the previous example, we mentioned the two types of components - the class-based components that can have internal state and the function component that are stateless, i.e. cannot have a state.

If you have any experience with React, you most certainly used the setState() method. Let's review this simple class component:

In order to manage the component's state, i.e. update the count value, React provides us with setState() method. It's a simple and easy to understand way for updating the current state, right?

So, each time we press the button, the count variable in the state will be incremented by 1 and the <Text> component will show it. Everything is good so far and works well!

This component is called STATEFUL, i.e. holding an internal state.

So, lets see an example of stateless component:

So, if you pass the name "Tom" to the Introducer component and run this code on a testing device, it will show the following text: "Hello, Tom".

This component is called STATELESS, i.e. it doesn't have an internal state.

At this point, I'm sure that you're confident enough with these two type of components and we can move on to the next part where the things get exciting! 🤪

Let's put the function component on steroids! 💪🏻

React 16.8 introduced a new interesting feature - React Hooks!

You'll be asking "Why is it so interesting?" and the answer would be - because the function components will be no more stateless!

And, as you must know, and I'm pretty sure, you already do - when using functions over classes, the code base is smaller, easier to understand, maintain and be tested!

Probably you're looking at this article and shouting - "No way! Prove it!"

For simplicity, I will use the class-based example from above and convert it into a stateful function component:

Look at it carefully! The first thing you will notice is that the rows decreased from 22 to 15, so it's ~38% change!

Let's review the code more thoroughly and explain each new thing!

  1. What is this strange construction at row 5?
    const [count, setCount] = useState(0)
    This is THE hook! This is how we use the useState() hook and adding state to our function component.There are two things that are important to understand and remember here:
    • useState() can accepts a default state which in our case is just the integer 0. What is important for you, is that the hook can accept not only objects but primitive values. This is not possible in the class-based state management where the state is just an object holding the state values.
    • The strange [count, setCount] construction is called "Array destructuring" and it's a JavaScript syntax for assigning named variables to the array items. At the bottom of this article, you will find an explanation with examples.In, our context, the first item: count, is holding our state value and the second item: setCount, is the update function we can use to change the count value, i.e. change the state.
  2. At row 9, you will see that we directly use the count variable and unlike in the class components via this.state.count
  3. And finally, the state update, at row 10, where we call the setCount() function and pass the incremented count value unlike in the class components via setState({ count: this.state.count + 1 })

It's pretty nice, eh?
Less code... and much more beautiful!

Usage examples

Using object as a state:

⚠️ Beware that the updating of the state object is not working like in the class components, i.e. the class component setState() is merging the object and the useState() hook's update function (setCount() in our example) is replacing it! So if you have an object like: { countOne: 10, countTwo: 20 } and you update it with setCount({ countOne: 22 }), the countTwo will be erased, i.e. the object { countOne: 10, countTwo: 20 } will be replaced with the passed to setCount - { countOne: 22 }!

Using multiple states in a single functional component:

As you can see, we can use any number of states in a single function component unlike in the class components.

What the heck are those [] mean? 🤔

As I mentioned above, this JavaScript syntax is called "Array destructuring".
The names on the left side are not part of the React API and you can name them whatever you want like:

With array destructuring we're making two new variables fruit and setFruit, where fruit is set to the first value returned by the useState(), and setFruit to the second. This is equivalent to the following code:

When we use useState() it returns two items:

  1. The first is the state value - primitive value or object
  2. The second is a function with which we can update the state value

In Conclusion

useState() is a great new addition to the React which enables the function component to be stateful. This is particularly good because it leads to a smaller codebase that is easier to understand and maintain as well as to be tested!

The great thing is that you can continue using your existing class components alongside the function ones as the Hooks API is backward compatible and won't break your existing code!

Happy exploring and coding, fellow developers! 👨‍💻