reactjs - 在 React Redux 中使用状态更改来触发模态
问题描述
我正在使用 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 和状态更改重新触发创建了某种渲染循环,但是当我将其切换为按钮时,模态渲染良好。我怎样才能获得状态更改以呈现模态一次(所以它的行为就像一个点击事件)?
非常感谢 :-)
解决方案
这是由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]
更改时运行包含的代码。
推荐阅读
- angular - 从 Angular 设置原生 web 组件的回调
- python - 如何处理folium中的事件?
- python - 如何按函数返回 *args、**kwargs
- wordpress - wordpress 500 内部服务器错误与 htaccess 和 404 在删除 htaccess 后除了 hompage 之外的所有页面都找不到
- objective-c - 如何在 Cocoa 应用程序中模拟鼠标点击?
- database - 为什么大型数据库通常实现为充满副本的分片而不是充满分片的副本?
- python - 计算订购数量是否不等于包装
- postgresql - 如何在 sequalize PostgreSQL 中根据用户 ID 对数据进行分组?
- html - 如何使用 bootstrap flex 方式使内框占据其父级的全高?
- c - 为什么STM32上返回数据为0?