为什么在我更改另一个组件中的状态后该函数不起作用?



这是我正在使用的三个组件,不包括在DOM中显示它们的组件,但这不是必需的。

在这里,我有一个父组件和两个子组件。

由于某种原因,当弹出窗口处于活动状态时,我单击">刷新子 1 组件"按钮,它将状态更改回Child1,但我丢失了该组件中的功能。因此,popUpToggle函数停止工作。

它以前工作正常。但是,当我再次单击刷新子 1 组件时,它开始工作。为什么?

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>
);
};

最新更新