How to Implement React State in React

This article provides a practical guide on how to implement and manage state within React functional components using the useState Hook. You will learn the core concept of React state, the syntax required to initialize it, and how to properly update state values to trigger component re-renders.

What is React State?

State represents the dynamic data inside a React component. Unlike props, which are passed down from parent components and are read-only, state is managed locally within the component itself. When the state of a component changes, React automatically re-renders that component to reflect the new data in the User Interface (UI).

Implementing State with the useState Hook

In modern React (version 16.8 and later), state is implemented in functional components using the useState Hook.

1. Import the Hook

To use state, you must first import the useState Hook from the React library at the top of your file:

import React, { useState } from 'react';

2. Initialize State

Inside your functional component, call useState and pass the initial value of your state as an argument. The hook returns an array containing two elements: the current state value and a function to update it. Use array destructuring to assign names to these elements:

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

3. Update the State

To change the state value, call the setter function and pass the new value. Never mutate the state variable directly (e.g., do not write count = count + 1).

Here is a complete, working example of a simple counter component:

import React, { useState } from 'react';

function Counter() {
  // 1. Initialize state variable 'count' with a value of 0
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Current Count: {count}</p>
      {/* 2. Update state when the button is clicked */}
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

export default Counter;

Updating State Based on Previous State

If your new state depends on the previous state value, pass a callback function to the setter function. This function receives the previous state as an argument and returns the updated state. This prevents race conditions and ensures you are working with the most current data:

setCount(prevCount => prevCount + 1);