React 函数组件中的 setState 如何工作?

how setState in react function component works?

我编写这段代码,我希望 A 为 8,但实际为 6。为什么? 如果我删除第 6 行,它会正常工作,但如果我没有在 setState 中使用回调,它会忽略它上面的所有行。

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

这些状态更新是异步的。它们可能会分批发送。无法确定前三个状态更新何时会 运行。这就是为什么使用回调始终是一种很好的做法,尤其是当您使用前一个状态值时。(您在这里使用的是模式,但使用的方式不同。)


setA((preA) => preA + 1) //Setting to 1 using previous Value
        setA(A + 1) //Setting to 1
        setA((preA) => 2) // Setting to 2 but not using previous Value
        setA((preA) => preA + 4) //Setting to 6 using previous Value


第 6 行将值设置为稍后在使用回调模式 (prevValue) 时使用的特定值。他们不会使用当时为 0 的 prev 值。

setA((preA) => 2) 只需 returns 2 并将 A 设置为 2。 因此在下一行之后 setA((preA) => preA + 4) 设置为 A2 + 4 = 6。 这样的问题可能有很多。请记住,console.log() 是所有开发者最好的礼物。

setA((preA) => 2)定义了一个函数,return值为2.
所以 A 设置为 2.

(last) 之后的行添加另一个 2,因此 A 变为 6,如下所示:

片段:

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


您可能总是想像这样将 n 添加到 prevA 以获得所需的 8:

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

片段:

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