React State

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';

Second, define a piece of state using the useState() function in the component:

const App = () => {
  const [state, setState] = useState(0);
  // ...
};

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);

In React, you must not change the state directly like:

state = newValue;

Instead, you use the setState() function to change the state:

setState(newValue);

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

Second, navigate to the counter project directory:

cd counter

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 the App component
  • The App.js file that stores the App 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 />);

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;

How it works.

First, import the useState function from the react library:

import { useState } from 'react';

Second, create the App component:

const App = () => { 
   // ...
}

Third, define a state for the App component called counter:

const [counter, setCounter] = useState(0);

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);

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>
  </>
);

Finally, export the App component:

export default App;

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;

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;
}

Second, import the App.css file to the App.js file:

import { useState } from 'react';
import './App.css';

// ....

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.

Was this helpful?