reactjs - 为什么我在另一个组件中更改了状态后该功能不起作用?
问题描述
这些是我正在使用的三个组件,不包括在 DOM 中显示它们的组件,但这不是必需的。
这里我有一个父组件和两个子组件。
由于某种原因,当弹出窗口处于活动状态时,我单击Refresh Child 1 Component按钮,它会将状态更改回Child1
,但我失去了该组件中的功能。因此该popUpToggle
功能停止工作。
它以前工作正常。但是,当我再次单击Refresh Child 1 Component时,它开始工作。这是为什么?
import React, { useState, useEffect } from 'react';
import Child1 from './child1'
import Child2 from './child2'
const Parent = () => {
const [display, setDisplay] = useState('');
const [popUp, setPopUp] = useState(false);
const [renderCount, setRenderCount] = useState(0);
const popUpToggle = () => {
setPopUp(!popUp)
console.log('PopUp Toggle ran')
};
const reRenderComponent= () => {
setRenderCount(renderCount + 1);
setDisplay(
<Child1
key={renderCount}
popUpToggle={popUpToggle}
renderCount={renderCount}
/>
);
popUpToggle();
console.log('reRenderComponent ran, and the key is ' + renderCount)
};
useEffect(() => {
setDisplay(
<Child1
key={renderCount}
popUpToggle={popUpToggle}
renderCount={renderCount}
/>
);
}, [])
return (
<div>
<button
style={{position: 'fixed', zIndex: '999', right: '0'}}
onClick={reRenderComponent}
>
Refresh Child 1 Component
</button>
{popUp ? <Child2 popUpToggle={popUpToggle}/> : null}
{display}
</div>
);
};
export default Parent;
孩子 1:
import React from 'react';
const Child1 = ({ popUpToggle, renderCount }) => {
return (
<>
<button onClick={popUpToggle}>
Pop Up Toggle function
</button>
<h1>Child 1 is up, count is {renderCount}</h1>
</>
);
};
export default Child1;
孩子 2:
import React, { useState } from 'react';
const Child2 = ({ popUpToggle }) => {
return (
<div
style={{
backgroundColor: 'rgba(0,0,0, .7)',
width: '100vw',
height: '100vh',
margin: '0',
}}
>
<h1>Child 2 is up</h1>
<h2>PopUp active</h2>
<button onClick={popUpToggle}>Toggle Pop Up</button>
</div>
);
};
export default Child2;
解决方案
setDisplay(<Child1 /*etc*/ />);
将元素放入状态通常不是一个好主意。它很容易导致与您所看到的完全相同的错误。除非您明确这样做,否则状态中的元素永远不会更新,因此它可以轻松引用过时的数据。在您的情况下,我认为问题在于子组件具有对 的陈旧引用,而后者又在其闭包popUpToggle
中有一个旧实例。popUp
更好的方法和标准方法是让您的状态只包含最少的数据。渲染时根据数据创建元素。这样,元素始终与最新数据同步。
在您的情况下,看起来所有数据都已经存在,因此我们不需要添加任何新的状态变量:
const Parent = () => {
const [popUp, setPopUp] = useState(false);
const [renderCount, setRenderCount] = useState(0);
const popUpToggle = () => {
setPopUp(prev => !prev);
};
const reRenderComponent = () => {
setRenderCount(prev => prev + 1);
popUpToggle();
};
return (
<div>
<button
style={{ position: "fixed", zIndex: "999", right: "0" }}
onClick={reRenderComponent}
>
Refresh Child 1 Component
</button>
{popUp && <Child2 popUpToggle={popUpToggle} />}
<Child1
key={renderCount}
popUpToggle={popUpToggle}
renderCount={renderCount}
/>
</div>
);
};
推荐阅读
- flutter - 如何为列表中的容器设置动画
- css - Position:fixed 在 bootstrap 4 中破坏网格
- reactjs - AWS Lambda 上的无服务器 Next.js
- php - 如何查询自定义帖子类型分类以创建模板页面的分类列表
- php - Drupal 8.6 如何禁用 HTTPS
- sql-server - 创建新的 SQL Server 2017 维护计划时出错
- java - 将 Content-type "message/rfc822" 的附件转换为 .msg 文件
- java - 如何修复服务器的输出以使其正确显示来自客户端的消息?
- node.js - 是否可以使用 GraphQL 查询 JSON 文件?
- oracle - 无法在 Oracle apex 中使用匿名块更新字段