【问题标题】:useEffect don't update when setState runs on Child Component当 setState 在子组件上运行时,useEffect 不会更新
【发布时间】:2022-07-26 22:39:09
【问题描述】:

我正在制作一个带有 react 的井字游戏,我将用于更改棋盘的父 setState 函数传递给子组件。

之后,我在父组件 (useEffect(()=> ... , [board])) 中放置了一个 useEffect,以便在此状态更改时执行操作。但是当我在孩子内部使用 setState 时,它​​什么也没做。下面的 console.log 显示为 true,这可能是 useEffect 没有更新的原因。

function handleClick(_, i:number) {

    setBoard(prevBoard => {
  
      const newBoard = board

      newBoard[i] = dictIconToValue[icon] as typeof prevBoard[0]
  
      console.log(newBoard == prevBoard)
  
      return newBoard
  
    })

...

}

【问题讨论】:

  • 如果新状态和旧状态的值相同,则不会触发重新渲染。顺便说一句,您应该分享更多关于您在父组件中的useEffect 中所做的事情以及如何在子组件中设置board 值的信息。这将有助于我们更好地了解您的问题。

标签: reactjs typescript


【解决方案1】:

下面的console.log显示为true,这可能是useEffect没有更新的原因。

就是这样。反应中的状态旨在是不可变的。当你调用 setBoard 时,react 将使用 === 检查将旧状态与新状态进行比较。如果它们相同,那么看起来没有任何变化,因此 react 会跳过重新渲染。 React 不会检查你的 state 中的属性以查看它们是否发生了变化,因为这可能会很昂贵。

相反,请确保创建新状态而不是修改旧状态:

setBoard(prevBoard => {
  const newBoard = [...board]; // <--- creating a shallow copy
  newBoard[i] = dictIconToValue[icon] as typeof prevBoard[0]
  return newBoard
})

【讨论】:

    【解决方案2】:

    就 React 而言,状态实际上并没有被更新,因为它仍然是同一个对象引用。您正在改变状态而不是创建新实例。

    这不会复制数组,它只是将一个新变量指向同一个引用:

    const newBoard = board
    

    因此,对newBoard 所做的任何更改都直接在状态实例上进行(对其进行变异)。相反,使用现有数组元素的副本创建一个新数组:

    const newBoard = [...board]
    

    在这种情况下,newBoard 完全是一个新的对象引用,所以当它被设置为状态时,React 会将其视为更新状态。

    【讨论】:

      猜你喜欢
      • 2021-10-02
      • 2021-04-19
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      • 2021-04-29
      • 2020-11-16
      • 1970-01-01
      • 2021-05-13
      相关资源
      最近更新 更多