Summary: in this tutorial, you will learn how to use the React State system to handle data that changes over time and control the behavior of a component.
Introduction to React State
The state is data that changes over time.
Typically, a React component has a state that controls its behaviors and appearance. To manage the component’s state, you use the React state system.
The following shows the steps for defining a piece of state in a React component:
First, import the useState
function from the react
library:
import { useState } from 'react';
Code language: JavaScript (javascript)
Second, define a piece of state using the useState()
function in the component:
const App = () => {
const [state, setState] = useState(0);
// ...
};
Code language: JavaScript (javascript)
The useState()
function returns an array that contains two variables:
- A state (
state
). - A function that changes the state (
setState
).
Because the useState()
function returns an array of two elements, we can use the array destructuring to assign the return value to variables.
By convention, if a state is name
, then the function that sets the state is setName
.
The 0
is the default value of the state when the component is initialized.
If the state is an array, you can set the default value to an empty array []
. Similarly, if the state is an object, you can set the default value of the state to an empty object {}
.
Third, change the state using the setState()
function:
setState(newValue);
Code language: JavaScript (javascript)
In React, you must not change the state directly like:
state = newValue;
Code language: JavaScript (javascript)
Instead, you use the setState()
function to change the state:
setState(newValue);
Code language: JavaScript (javascript)
Use the setState()
function to change the state. Never change the state by modifying its value directly.
When a state changes, React will rerender the component by executing the function that creates the component.
If you modify the state directly without using the setState()
function, React will be unable to rerender the component, which causes unexpected behaviors.
Typically, the state of a component is changed when you interact with it like clicking a button. To handle events in React, you use the React Event system.
The Counter App
We’ll build the following Counter React App:
If you click the +
button, the number will be incremented. If you click the -
button, the number will be decremented.
Setting up a new project
First, open a terminal and run the npx create-react-app
to create the counter app:
npx create-react-app counter
Code language: JavaScript (javascript)
Second, navigate to the counter
project directory:
cd counter
Code language: JavaScript (javascript)
Third, delete all files in the src
directory under the project directory.
Finally, create the index.js
and App.js
files in the src
directory.
- The
index.js
file displays theApp
component - The
App.js
file that stores theApp
component.
index.js
The index.js
file shows the App
component on the screen:
import ReactDOM from 'react-dom/client';
import App from './App.js';
const el = document.querySelector('#root');
const root = ReactDOM.createRoot(el);
root.render(<App />);
Code language: JavaScript (javascript)
App.js
import { useState } from 'react';
const App = () => {
const [counter, setCounter] = useState(0);
const increment = () => setCounter(counter + 1);
const decrement = () => setCounter(counter - 1);
return (
<>
<header>
<h1>Counter</h1>
</header>
<main>
<p>{counter}</p>
<div>
<button type="button" onClick={increment}>
-
</button>
<button type="button" onClick={decrement}>
+
</button>
</div>
</main>
</>
);
};
export default App;
Code language: JavaScript (javascript)
How it works.
First, import the useState
function from the react
library:
import { useState } from 'react';
Code language: JavaScript (javascript)
Second, create the App
component:
const App = () => {
// ...
}
Code language: JavaScript (javascript)
Third, define a state for the App
component called counter
:
const [counter, setCounter] = useState(0);
Code language: JavaScript (javascript)
We set the default value for the counter
state to 0
.
Fourth, define two functions that handle the click events:
const increment = () => setCounter(counter + 1);
const decrement = () => setCounter(counter - 1);
Code language: JavaScript (javascript)
The increment()
function will execute when the increment
button is clicked, and the decrement()
function will execute when the decrement
button is clicked.
Fifth, wire the decrement()
function in the onClick
event of the decrement
button (-) and the increment()
function in the onClick
event of the increment
button (+). Also, display the counter state in the <p>
tag.
return (
<>
<header>
<h1>Counter</h1>
</header>
<main>
<p>{counter}</p>
<div>
<button type="button" onClick={decrement}>
-
</button>
<button type="button" onClick={increment}>
+
</button>
</div>
</main>
</>
);
Code language: JavaScript (javascript)
Finally, export the App
component:
export default App;
Code language: JavaScript (javascript)
To make the code more concise, you can use arrow functions directly in the onClick
prop instead of defining two additional functions increment()
and decrement()
:
import { useState } from 'react';
const App = () => {
const [counter, setCounter] = useState(0);
return (
<>
<header>
<h1>Counter</h1>
</header>
<main>
<p>{counter}</p>
<div>
<button type="button" onClick={() => setCounter(counter - 1)}>
-
</button>
<button type="button" onClick={() => setCounter(counter + 1)}>
+
</button>
</div>
</main>
</>
);
};
export default App;
Code language: JavaScript (javascript)
Styling the App component
First, create an App.css
file in the src
directory with the following code:
App.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
font-size: 1rem;
line-height: 1.5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
main {
display: flex;
flex-direction: column;
align-items: center;
}
main > p {
font-size: 5rem;
color: gray;
}
main > div {
display: flex;
gap: 1rem;
}
h1 {
color: lightgray;
}
button {
padding: 1rem;
border: none;
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
background-color: #f9dc5c;
}
Code language: CSS (css)
Second, import the App.css
file to the App.js
file:
import { useState } from 'react';
import './App.css';
// ....
Code language: JavaScript (javascript)
Third, run the app and click the decrease and increase button to see the effect:
npm run
Summary
- Use the
useState()
function to create a state and a function that changes the state. - Always use
setState()
function to change the state. - React rerenders the component when its state changes.