React Hook useState

To keep track of how our data changes in React, we use state management. By doing so, we can create dynamic apps that respond to user input.

There are several ways to manage state in React, including Redux and Class-based state management. In this article, we’ll see how to use React useState to manage state on functional components.

I. What is React useState()?

React useState hook lets us add state to function components.

useState takes an initial state as an argument and returns an array with 2 values:

  • The first value represents the current state
  • The second value is a function to update this state

To import useState:

import { useState } from 'react';

In this example, we pass an empty string as our default state

const [state, setState] = React.useState('');

II. useState Examples

1. Basic

In this basic example, we implement a useState hook to create a simple Count App.

import React, { useState } from 'react'

export default function App() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <h1>Counter App</h1>
            <button onClick={() => setCount(count + 1)}>Count {count}</button>
        </div>
    )
}

2. useState - Previous states

In this example, we’ll set state based on previous state value.

Once again, we’ll create a Counter App. However, this time it will have buttons to increment, decrement and reset the count value.

To update the value based on the previous value, we pass in a function that takes the previous state value

onClick={() => setCount(prevCount => prevCount - 1)}

Don’t do this

setCount(count - 1)

Put it all together

import React, { useState } from 'react'

export default function App() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <h1>Counter App</h1>
            <h2>{count}</h2>
            <button onClick={() => setCount(prevCount => prevCount - 1)}>
                Decrease
            </button>
            <button onClick={() => setCount(0)}>
                Reset
            </button>
            <button onClick={() => setCount(prevCount => prevCount + 1)}>
                Increase
            </button>
        </div>
    )
}

3. useState - Array

In this example, the default state value wil be an array.

We will create 2 buttons to

  • remove each person on the list
  • remove the whole list at once
import React, { useState } from 'react'

const UseStateArray = () => {
    const data = [
        { id: 1, name: 'Anna' },
        { id: 2, name: 'Joe' },
        { id: 3, name: 'Pan' },
        { id: 4, name: 'Ron' },
    ];

    const [people, setPeople] = useState(data);

    // Set removeItem function
    const removeItem = (id) => {
        let newPeople = people.filter((person) => person.id !== id);
        setPeople(newPeople);
    };

    return (
        <div>
            {people.map((person) => {
            const { id, name } = person;
            return (
                <div key={id} className='item'>
                    <h4>{name}</h4>
                    <button onClick={() => removeItem(id)}>Remove</button>
                </div>
            );
            })}

            // Button to remove the whole list
            <button className='btn' onClick={() => setPeople([])}>
                Clear list
            </button>
        </div>
    )
}
export default UseStateArray;

4. useState - Object

In this example, the default state value wil be an object. We will create a button to change the message.

If we use an object inside our state, when updating the object, we need to make sure we update all values in the old object as well because they don’t get merge automatically.

import React, { useState } from 'react';

const UseStateObject = () => {
  const [person, setPerson] = useState({
    name: 'Anna',
    age: 20,
    message: 'Random Message',
  });

  const changeMessage = () => {
    setPerson({ ...person, message: 'Hello World' });
  };

  return (
    <div>
      <h3>{person.name}</h3>
      <h3>{person.age}</h3>
      <h4>{person.message}</h4>
      <button className='btn' onClick={changeMessage}>
        Change message
      </button>
    </div>
  );
};

export default UseStateObject;

To preserve all values in the object, we use spread operator: …person