Skip to main content

5 use cases of the useState ReactJS hook

Updated 4 min readMarkdown
Part of seriesReactJS use cases
5 use cases of the useState ReactJS hook

useState is a Hook that needs to be called inside a function component to add some local state to it. React will preserve this state between component re-renders.

There are many use cases for the useState hook, but in this article, I will focus on the following five:

useState use cases

  • State management
  • Conditional rendering
  • Toggle flags (true/false)
  • Counter
  • Get API data and store it in state

State management

Let's start with a warning: don't write code in this way, because it will create an infinite loop:

import { useState } from "react";

const UseCaseStateManagement = props => {
    const [state, setState] = useState('initial value');

    setState('new value');
    console.log(state);

    return (
        <>
            <h2>useState use case</h2>
            <h3>State management</h3>
            <hr />
            <p>{state}</p>
        </>
    );
};

export default UseCaseStateManagement;

The loop is created because the initial render calls the state update function setState, which in time triggers a re-render and a new function evaluation.

If we want to change a state due to an action performed by the user, we can do this:

import { useState } from "react";

const UseCaseStateManagement = props => {
    const [state, setState] = useState('initial value');

    console.log('🔄 This is a re-render');

    const clickHandler = () => {
        setState('new value');
    };

    return (
        <>
            <h2>useState use case</h2>
            <h3>State management</h3>
            <hr />
            <button onClick={clickHandler}>Set state</button>
            <p>{state}</p>
        </>
    );
};

export default UseCaseStateManagement;

That state will be preserved across component re-renders and we will be able to make use of it in the newest re-render.

Conditional rendering

We can use a state to conditionally render a component or part of it.

import { useState } from "react";

const UseCaseConditionalRender = props => {
    const [condition, setCondition] = useState(false);

    const clickHandler = () => {
        setCondition(true);
    };

    return (
        <>
            <hr />
            <h2>useState use case</h2>
            <h3>Conditional Rendering</h3>
            <button onClick={clickHandler}>Set condition</button>
            {condition && <p>Hello!</p>}
        </>
    );
};

export default UseCaseConditionalRender;

Toggle flags

useState can be used to toggle between two values, usually true and false, in order to toggle a flag, such as the display mode:

import { useState } from 'react';
import classes from './UseCaseToggle.module.css';

const UseCaseToggle = props => {
    const [mode, setMode] = useState(false);

    // Use setState function form because the new state depends on the previous one
    const clickHandler = () => {
        setMode(prevState => !prevState);
    };

    const toggledClass = mode ? classes.light : classes.dark;

    return (
        <div className={toggledClass}>
            <hr />
            <h2>useState use case</h2>
            <h3>Toggle flags</h3>
            <button onClick={clickHandler}>Toggle display mode</button>
        </div>
    );
};

export default UseCaseToggle;

The result will be an alternation between dark and light mode on the component.

Counter

useState can be used to keep track of a variable through multiple re-renders, such as in a counter application:

import { useState } from "react";

const UseCaseCounter = props => {
    const [counter, setCounter] = useState(0);

    // Use setState function form because the new state depends on the previous one
    const clickHandlerDecrease = () => {
        // Converting the prevState to number to avoid errors
        setCounter(prevState => +prevState - 1);
    };

    const clickHandlerIncrease = () => {
        setCounter(prevState => +prevState + 1);
    };

    return (
        <>
            <hr />
            <h2>useState use case</h2>
            <h3>Counter</h3>
            <button onClick={clickHandlerDecrease}>--</button>
            <span> {counter} </span>
            <button onClick={clickHandlerIncrease}>++</button>
        </>
    );
};

export default UseCaseCounter;

Get API data and store it in state

A more complex use of this hook is presented when we need to interact with an API. In this case, we can use a state to store the response of a fetch() to the API, and the state of a spinner that will indicate if the data is being fetched.

import { useState } from "react";

const UseCaseApi = props => {
    const [starship, setStarship] = useState('');
    const [isLoading, setIsLoading] = useState(false);

    const clickHandler = async () => {
        setIsLoading(true);

        const response = await fetch('https://swapi.dev/api/starships/10');
        const data = await response.json();
        setStarship(JSON.stringify(data, null, "\t"));

        setIsLoading(false);
    };

    let message = '';
    if (isLoading) {
        message = <p>Getting data... 🚀</p>;
    }

    return (
        <>
            <hr />
            <h2>useState use case</h2>
            <h3>Get API data and store it in state</h3>
            <button onClick={clickHandler}>Get Millennium Falcon data</button>
            <p>{message}</p>
            <pre>{starship}</pre>
        </>
    );
};

export default UseCaseApi;

You can watch all these examples live here.

You can also take a look at the code in this repository.


🗞️ NEWSLETTER - If you want to hear about my latest articles and interesting software development content, subscribe to my newsletter.

🐦 TWITTER - Follow me on Twitter.

About the author

  • I’m a Web Developer based in Adelaide, Australia. Even though I have a Telecommunications Engineering degree and an MBA, coding is my passion and my new professional career focus. Developing applications for the web has become my drive.

No comments yet. Be the first to comment.

More from this blog