State management is one of the most important parts of any application. Understanding state management is incredibly important as current trend heavily focuses on robust way to manage state of the application as data are constantly read or modified by the users.
In this example we are going make simple counter app with two buttons in order to understand the state management of a react application. We will implement counter button functionality using useState Hooks.
So without further ado let’s create a react app by running the following command.
npx create-react-app my-app
cd my-app
npm start
After little bit of clean up, this is our App.js file looks like as of now.
import React, { useState } from 'react';'
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<button>-</button>
<p>You clicked 0 times</p>
<button>+</button>
</div>
);
}
Where can we use useState Hooks?
We can only use useState Hooks inside of a function component. This is not possible in a class components. We can only mix classes and function components with Hooks in a single tree. There for we must to use function components to use Hooks.
Only Hooks at the top level
Do not call Hooks inside loops, conditions or nested functions. Always use Hooks at the top level of your React function before any early returns. Hooks must call in the same order each time a components renders. Thats what allow React to correctly preserve the state of Hooks between multiple useState and useEffect calls.
function Form() {
// 1. Use the name state variable
const [name, setName] = useState('Mary');
// 2. Use an effect for persisting the form
useEffect(function persistForm() {
localStorage.setItem('formData', name);
});
// 3. Use the surname state variable
const [surname, setSurname] = useState('Poppins');
// 4. Use an effect for updating the title
useEffect(function updateTitle() {
document.title = name + ' ' + surname;
});
// ...
}
So from this example above, how React knows which State corresponds to which useState call?
Well, React relies on the order in which Hooks are called.
// ------------
// First render
// ------------
useState('Mary') // 1. Initialize the name state variable with 'Mary'
useEffect(persistForm) // 2. Add an effect for persisting the form
useState('Poppins') // 3. Initialize the surname state variable with 'Poppins'
useEffect(updateTitle) // 4. Add an effect for updating the title
// -------------
// Second render
// -------------
useState('Mary') // 1. Read the name state variable (argument is ignored)
useEffect(persistForm) // 2. Replace the effect for persisting the form
useState('Poppins') // 3. Read the surname state variable (argument is ignored)
useEffect(updateTitle) // 4. Replace the effect for updating the title
Let’s go back to useState and how to use it.
To use useState Hooks, all we need to do is to call useState function and pass the default state inside the parameter. useState return arrays of values. As we know array always have two values.
Now focus on setCount value and how we set the value inside the component. To do that, we create onClick function inside the button.
import React, { useState } from 'react';'
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={documentCount}>-</button>
<span><p>You clicked 0 times</p><span>
<button>+</button>
</div>
);
}
Create documentCount function which will remove one fro our count every time as we click the button.
function documentCount() {
setCount(prevCount => prevCount - 1)
}
Now we can able to update our count by decreasing by one each time as we click the button and then render our component for the new value.
That all for now. We will continue writing more tutorials on state management in future.
Full code: ReactStateManagement