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

问题描述 投票:0回答:3

我编写了这段代码,我期望

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
reactjs react-hooks setstate
3个回答
0
投票

setA((preA) => 2)
定义了一个函数,返回值为
2

因此
A
设置为 2。

(最后)之后的行添加了另一个

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>


0
投票

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


0
投票

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


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 的上一个值。

© www.soinside.com 2019 - 2024. All rights reserved.