reactjsreact-hookssetstate

How does setState work in the React function component?


I wrote this code and I expect A to be 8 but it will be 6. Why? If I deleted line 6 it would work correctly but if I did not use the callback in setState it would ignore all the lines above it.

import React, { useState, useEffect } from 'react'
function SameSet() {
    const [A, setA] = useState(0)
    const go = () => {
        setA((preA) => preA + 1)
        setA(A + 1)
        setA((preA) => 2)
        setA((preA) => preA + 4)
    }
    return (
        <div>
            {A}
            <button onClick={() => {
                go()
            }}> ok</button>
        </div>
    )
}
export default SameSet

Solution

  • setA((preA) => 2) defines a function, with a return value of 2.
    So A is set to 2.

    The line after (last) adds another 2, so A becomes 6 as shown here:

    Snippet:

    // Get a hook function
    const {useState} = React;
    
    const SameSet = () => {
        const [A, setA] = useState(0);
        const go = () => {
            setA((preA) => preA + 1)  // 0 + 1 = 1
            setA(A + 1)               // 1 + 1 = 2
            setA((preA) => 2)         // 2
            setA((preA) => preA + 4)  // 2 + 2 = 4
        }
        return (
            <div>
                {A}
                <button onClick={() => {
                    go()
                }}> ok</button>
            </div>
        )
    }
    ReactDOM.render(<SameSet />, document.getElementById("react"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="react"></div>


    You'd probably always want to add n to the prevA like so to get the desired 8:

    setA((preA) => preA + 1);
    setA((preA) => preA + 1);
    setA((preA) => preA + 2);
    setA((preA) => preA + 4);
    

    Snippet:

    // Get a hook function
    const {useState} = React;
    
    const SameSet = () => {
        const [A, setA] = useState(0);
        const go = () => {
          setA((preA) => preA + 1);
          setA((preA) => preA + 1);
          setA((preA) => preA + 2);
          setA((preA) => preA + 4);
        }
        return (
            <div>
                {A}
                <button onClick={() => {
                    go()
                }}> ok</button>
            </div>
        )
    }
    ReactDOM.render(<SameSet />, document.getElementById("react"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="react"></div>