react 中 setstate 函数如何工作

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

简单的例子:我想从牌堆中选择一张牌并将其带到我的手上。当我选择卡片时,我将其附加到“chosenCard”状态。所以,当我选择这张卡时,我想做下一步:

setMyCards(prevState => [...prevState, {...chosenCard}])
setChosenCard(null)

问题是:可以吗?更改状态是异步的,那么第一个函数将在第二个函数之前正常工作是否准确?如果是,为什么?有没有可能,第二个函数可以改变状态,而第一个函数将工作不正确(也许在更复杂的情况下)?

reactjs react-hooks frontend
1个回答
0
投票

如果我理解正确的话,您担心第二行代码可能会在第一行代码之前生效,从而有效地将

null
值添加到
myCards

您可以放心地假设这不会发生。当执行

setMyCards
时,
chosenCard
还不会重置为
null
。读取第一行中
chosenCard
的值不是异步的,因此代码中后面发生的任何事情都不会产生任何影响。

如果你有相反的执行顺序,你可能会遇到不同的情况:

setChosenCard({ newValue: 42 })
setMyCards(prevState => [...prevState, {...chosenCard}])

在这种情况下,

chosenCard
的新值仅在下一个渲染周期中变得可见,而
setMyCards
还不会拾取它。

有不同的方法来处理这个问题:

设置状态变量值后不要立即读取状态变量

const newValue = { newValue: 42 }
setChosenCard(newValue)
setMyCards(prevState => [...prevState, newValue])

使用useReducer

如果您的应用程序经常修改多个相互依赖的状态变量,那么最好使用

useReducer
而不是
useState
。它将允许您定义单个操作,如果调度该操作,则会同时更新应用程序状态中的
chosenCard
myCards

使用 useEffect 管理状态依赖关系

useEffect(
  ()=> chosenCard !== null && setMyCards(prevState => [...prevState, {...chosenCard}]),
  [chosenCard]
)

这将确保仅在状态更改生效后才调用

setMyCards
。然而,不鼓励过度使用 useEffect,因为这会导致很难推断隐式状态更改:you-might-not-need-an-effect

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