React Hooks - Use State Hook Tutorial
React Hooks - Use State Hook Tutorial

Hello and welcome back to the channel. In this video you will learn the most popular hook inside react hooks and it's useState hook.
Let's jump right into it.

Here I have empty create-react-app project where we can directly start writing code. If you don't know how to generate react project with create-react-app I made a video on that so go check it out first.

I you can see in browser I have just a single h1 tag and it's our App.js component. Let's have a look. So it's a normal stateless React component with markup inside.

As we are using React bigger than 16 version (actually 17) we can use hooks inside without installing any additional packages.


So the most important and used hook is useState hook. It brings state in our stateless components. Let's use it now.

For example we want to create isLoading property and toggle it when we click on the button. It would be nice for login or register form.

So first of all we need to import useState hook from react.

import React, { useState } from "react";

So useState is just a function. Now we can call it inside our component.

const [count, setCount] = useState(0);

So this is quite an interesting syntax. Here we called useState and set inside 0. This is the default value of the state that we want to create. On the left you can see destructuring of the array from which we are getting 2 local variables count and setCount. If you don't know what is destructuring it's direct creating local variables from object or array. In this case useState returns us array with 2 elements. The first element is a value and the second is a function setter which we can use to change our value of the state. As we wanted to create state for count variable we named first element count. The second element is a setter so we normally name setters starting from the word set. Like setCount.

Now let's use it. First of all we can render count property.

<p>You clicked {count} times</p>

As you can see in browser we directly rendered our default value zero.

But we want of course to change the count after we clicked on the button. So let's add a click event and call setCount inside.

const incrementCount = () => {
  setCount(count + 1)
}
<button onClick={incrementCount}>Click me</button>

As you can see after clicking on the button our counter is directly changed.

So this is exactly how useState hook allow you to create state inside functional components.

And now some words about what happens when we click on the button and how does it work? So every time when we click on the button we are calling setter on our state. And changing of the state triggers rerendering of our component. If we just write console.log inside our function you can see that react rerenders the component every time when we change the state.

function App() {
  console.log('rerender')
  ...
}

Also it's important to remember that hooks can't be wrote in any nested functions or operators. They must be on the root level of our component in other way React can't use them correctly. Luckily if we try to do that React will throw us an error.

if (true) {
  setCount(2)
}

Also we can pass a function inside a useState hook. As you can see actually we can read the value of the count directly as from local variable. But the problem here is that inside single render if we change our state several times it won't change the state. The state will be changed only after the rerender. Which means that if we put twice setCount +1 it will change it only once.

const incrementCount = () => {
  setCount(count + 1)
  setCount(count + 1)
}

To fix this we need to pass a function inside because then we get access to the previous value.

const incrementCount = () => {
  setCount(prevCount => prevCount + 1)
  setCount(prevCount => prevCount + 1)
}

But you might ask: "I always created an object with properties inside in classes but here we have only single field". This is true and you can create object with properties inside but this approach is not recommended. Why? Because it's more difficult to change an object properties than just a single value. This is why normally people create useState hook for each variable in their component. If we need 10 state properties we call 10 lines of useState. This is much easier to maintain at the end then a huge object.

const [state, setState] = useState({count: 0, name: ''})


const incrementCount = () => {
  setCount(prevState =>  ({
    ...prevState,
    count: prevState.count + 1
  }))
}

It's much easier to split states in 2 different properties.

const [count, setCount] = useState(0)
const [name, setName] = useState('')


One more important thing to know is that we can give an initial value to a useState as a function. Normally it's completely fine it we just set a value there. But this value will be set again and again after every render. So it may become slow if we are doing some heavy calculations when we are getting initial value. This is why we can provide a function inside an it will be run only on the very first render.

const [count, setCount] = useState(() => {
  console.log('setting default value once')
  return 0
});

What is more important that there is no magic in hooks at all. Every time when we change the state react simply renders a component passing inside our new state. You can imagine this like a stateless component with props and every time react simply throws inside new props. But we will talk deeper about rerendering in the next videos.

So this was the most popular hook inside react hooks.

If "React hooks for beginners" is too easy for you I have a full hooks course which is going 8 hours where we are creating real application from scratch. I will link it down in the description below.

📚 Source code of what we've done