反应状态改变,但组件不重新渲染

React state changes, but component doesn't re-render

如有任何帮助,我们将不胜感激。我从外部数据库获取数据并将其与可观察对象一起输入。当玩家状态改变时组件更新,但当怪物状态改变时组件不更新。

通过使用 React 开发人员工具调试组件,我可以看到状态是正确的并且填充了非零数据。如果我强制玩家再次更新,它确实会正确地重新绘制怪物,但 setMonsters 本身不会导致重新渲染。

export default () => {
  const [players, setPlayers] = useState({})
  const [monsters, setMonsters] = useState({})

  useEffect(() => {
    const playersSub = players$.subscribe(setPlayers)
    const monstersSub = monsters$.subscribe(x => {
      console.log('should be re-rendering...')
      setMonsters(x)
    })

    return () => {
      playersSub.unsubscribe()
      monstersSub.unsubscribe()
    }
  }, [])

  return (
    <Section style={{ backgroundColor: medium, borderRadius: '.5rem', flex: '1 0 0' }}>
      {Object.entries(players).map(([key, x], i) => {
        if (!x.investigator) return <div key={key} />
        return <Player player={x} key={key} />
      })}
      {Object.entries(monsters).map(([key, x]) => {
        console.log('what is going on?')
        return <Monster monster={x} key={key} />
      })}
    </Section>
  )
}

奇怪的是,当我刷新页面时,它会更新并在关闭前的几分之一秒内显示正确的呈现。

编辑

好的,我“修复”了它,但我仍然想知道是什么导致了这个问题,如果有人能为我阐明这个问题的话。

对我来说,修复和问题一样奇怪,我认为自己对 React 和 RxJS 相当熟悉。

我更改了对此的订阅。

  useEffect(() => {
    const playersSub = players$.subscribe(setPlayers)
    const monstersSub = monsters$.subscribe(x => {
      setMonsters({ ...x })
    })

    return () => {
      playersSub.unsubscribe()
      monstersSub.unsubscribe()
    }
  }, [])

现在它按预期工作了。这似乎不应该做任何事情。

React 使用Object.is() 相等(引用)来判断状态是否已经更新。我们不应该直接改变状态,就好像你向它发送相同的引用一样,它只是不知道。

您可以发送一个全新的副本,就像您在工作版本中所做的那样,或者使用采用更新程序函数的语法从当前状态设置状态。