【问题标题】:Using state change to trigger modal in React Redux在 React Redux 中使用状态更改来触发模态
【发布时间】:2021-02-22 19:45:56
【问题描述】:

我正在使用 React Redux 构建一个游戏,并且我有一个条件,即在发牌时,如果牌超过一定数量,我希望放置一个模式,以便用户可以选择一个丢弃。

我在游戏逻辑中通过将名为“cardHandOverflow”的状态的一部分切换为 true 来执行此操作,并且我希望模态在这种情况下呈现。我为此使用 React Modal 库。

但是我得到了错误

react-dom.development.js:14997 Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

这是我使用的代码:

export const CardHand: React.FC = () => {
  const cardHandOverflow = useSelector((state: RootState) => state.gameStateReducer.players.filter(player => player.id === Player.id)[0].cardHandOverflow);
  
  const [modalIsOpen, setIsOpen] = useState(false);

  const closeModal = () => {
    setIsOpen(false)
  }

  if (cardHandOverflow) {
    setIsOpen(true)
  }

  return (
    <>
      {modalIsOpen ? 
        <DiscardModal 
          modalIsOpen={modalIsOpen} 
          closeModal={closeModal}
          discardableCards={cards}
        /> : null}
    </>
  )

很明显,它使用 useSelector 和状态更改重新触发创建了某种渲染循环,但是当我将其切换为按钮时,模态渲染良好。我怎样才能让状态改变来渲染一次模态(所以它就像一个点击事件)?

非常感谢:-)

【问题讨论】:

  • if 语句应该放在useEffect 中,例如useEffect(() =&gt; { if (cardHandOverflow) { setIsOpen(true); }}, [cardHandOverflow, setIsOpen])
  • @JacobSmit 谢谢,这行得通。如果是答案,请将其标记为正确

标签: reactjs redux react-hooks react-modal


【解决方案1】:

这是由setIsOpen(true); 引起的,而cardHandOverflow 是真实的。

setIsOpen 会导致重新渲染,即使值没有更改,并且由于它直接是您的函数组件逻辑的一部分,所以当cardHandOverflow 为真时,它将运行渲染。

为了避免这些循环,你应该使用 React 提供的钩子,在这种情况下useEffect 是最合适的。

export const CardHand: React.FC = () => {
    const cardHandOverflow = useSelector((state: RootState) => state.gameStateReducer.players.filter(player => player.id === Player.id)[0].cardHandOverflow);
    
    const [modalIsOpen, setIsOpen] = useState(false);

    const closeModal = () => {
        setIsOpen(false)
    }

    useEffect(() => {
        if (cardHandOverflow) {
            setIsOpen(true)
        }
    }, [cardHandOverflow, setIsOpen])

    return (
        <>
        {modalIsOpen ? 
            <DiscardModal 
            modalIsOpen={modalIsOpen} 
            closeModal={closeModal}
            discardableCards={cards}
            /> : null}
        </>
    )
}

useEffect 只会在组件挂载时以及依赖数组 [cardHandOverflow, setIsOpen] 中的值发生变化时运行包含的代码。

【讨论】:

    猜你喜欢
    • 2016-08-31
    • 2018-08-09
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 2016-11-26
    • 1970-01-01
    • 1970-01-01
    • 2020-07-26
    相关资源
    最近更新 更多