React子组件状态在父组件重新呈现后丢失



我正在使用React钩子为父/子组件。

现在我的父组件(companyIcon)中有了状态,我需要根据子组件中的一些验证来更新它。我将validationCallback作为一个回调函数传递给子组件和更新我的父状态基于价值的孩子。

现在的问题是,在我更新父组件状态后,子组件中的状态值被重置。我在下面的实现中做错了什么?

function ParentComp(props) {
const [companyIcon, setCompanyIcon] = useState({ name: "icon", value: '' });
const validationCallback = useCallback((tabId, hasError) => {
if (hasError) {
setCompanyIcon(prevItem => ({ ...prevItem, value: 'error'}));
// AFTER ABOVE LINE IS EXECUTED, my Child component state "myAddress" is lost i.e. it seems to reset back to empty value.
}
}, []);

const MyChildCmp = (props) => { 
const [myAddress, setmyAddress] = useState('');
useEffect(() => {
if (myAddressExceptions.length > 0) {
props.validationCallback('MyInfo', true);
} else {
props.validationCallback('MyInfo', false);
}
}, [myAddressExceptions])

const handlemyAddressChange = (event) => {        
//setmyAddress(event.target.value);
//setmyAddressExceptions(event.target.value);
console.log(myAddressExceptions);
}
return (
<>
<div className="row" style={{ display: 'flex', flexDirection: 'row', width: '1000px'}}>
<div style={{ width: '20%'}}>
<FormField 
label='Company Address' 
required
helperText={mergedErrorMessages(myAddressExceptions)}
validationState={
myAddressExceptions[0] ? myAddressExceptions[0].type : ''
}
>
<Input id='myAddress'
value={myAddress}
//onChange={handlemyAddressChange}
onChange={({ target: { value } }) => {
validateInputValue(value);
}}
onBlur={handleBlur}
inputProps={{maxLength: 9}} />
</FormField>
</div>
</div>
</>
); 
}
return (
<div className="mainBlock">
Parent : {companyIcon}
{displayMyChild && <MyChildCmp validationCallback={validationCallback}/>}
</div>
)
}
export default withRouter(ParentComp);

以下是在child中丢失状态的一些原因(可能还有更多,但这些都适用于您):

{displayMyChild && <MyChildCmp validationCallback={validationCallback}/>}

如果在某一点displayMyChild为真,则为falsy,这意味着组件MyChildCmp将得到卸载,因此其所有状态将消失。

但是现在,即使你没有那个条件并且渲染MyChildCmp总是你仍然会遇到类似的问题,这是因为你在另一个组件中定义了MyChildCmp。当你这样做时,在父组件的每次渲染中,函数MyChildCmp被重新创建,react的协调算法认为你在下一次渲染中呈现了一个不同的组件类型,所以它将销毁组件实例。将该组件的定义移出父组件。

最新更新