道具更改不触发 useEffect
Prop change not triggering useEffect
我有一个带有 useEffect 的 React 组件,当 props 改变时它不会被触发。我希望这个组件根据道具更新它显示的内容。但是,当 prop 发生变化时,什么也没有发生。
为了调试,我添加了一个可以手动更新值的按钮,效果很好。我就是一辈子都无法将 useEffect 设置为 运行。
const ReadOnly = (props: WidgetProps) => {
const [value, setValue] = React.useState('No Value');
const { formContext } = props;
const firstName = () => formContext.queryData[0]?.basicInformation?.firstName ?? 'No value';
// This only runs once when the component is first rendered never fired when formContext updates.
React.useEffect(() => {
setValue(firstName());
}, [formContext]);
// This correctly updates the value
const onClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();
setValue(firstName());
};
return (
<>
<p>{value}</p>
<Button onClick={onClick}>Update Value</Button>
</>
);
};
export default ReadOnly;
我曾尝试将 useEffect 函数监视的值从 formContext
更改为 formContext.queryData[0].basicInformation.firstName
,但没有效果。我也尝试过使用 props
代替。我什至尝试完全删除 watch 数组,希望它只是垃圾邮件更新,但什么也没有。
关于如何实现这一点有什么建议吗?我知道该值正在传递到组件,因为当我按下按钮时它会起作用。当我在网页上的 React 检查器中检查它时,我可以清楚地看到值就在那里。干杯。
编辑:
该组件被用作 react-jsonschema-form 的小部件。基本上,每次更新 formData
时,我都会将其传递回 formContext
。 formContext
是我可以将其他数据获取到该小部件的唯一方法。下面是我正在做的事情的精简版。
const [formDataAndIncludings, setFormDataAndIncludings] = React.useState<any>(null);
ClientRect.useEffect(() => {
...
// Initial loading of formDataAndIncludings
...
}, [])
const onChange = (e: IChangeEvent<any>) => {
const newFormDataAndIncludings = { ...formDataAndIncludings };
newFormDataAndIncludings.queryData[0] = e.formData;
setFormDataAndIncludings(newFormDataAndIncludings);
};
return (
<Form
...
onChange={onChange}
formContext={formDataAndIncludings}
...
/>
)
状态直接在父级 onChange
中发生变化,因此 ReadOnly
组件中的 useEffect 未被触发。
更新你的 onChange
const onChange = (e: IChangeEvent<any>) => {
setFormDataAndIncludings(prev => ({
...prev ,
queryData : [
e.formData,
...prev.queryData.slice(0,1)
]
}))
//const newFormDataAndIncludings = { ...formDataAndIncludings };
//newFormDataAndIncludings.queryData[0] = e.formData;
//setFormDataAndIncludings(newFormDataAndIncludings);
};
照常提供useEffect依赖
React.useEffect(() => {
setValue(firstName());
}, [formContext]);
我有一个带有 useEffect 的 React 组件,当 props 改变时它不会被触发。我希望这个组件根据道具更新它显示的内容。但是,当 prop 发生变化时,什么也没有发生。
为了调试,我添加了一个可以手动更新值的按钮,效果很好。我就是一辈子都无法将 useEffect 设置为 运行。
const ReadOnly = (props: WidgetProps) => {
const [value, setValue] = React.useState('No Value');
const { formContext } = props;
const firstName = () => formContext.queryData[0]?.basicInformation?.firstName ?? 'No value';
// This only runs once when the component is first rendered never fired when formContext updates.
React.useEffect(() => {
setValue(firstName());
}, [formContext]);
// This correctly updates the value
const onClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();
setValue(firstName());
};
return (
<>
<p>{value}</p>
<Button onClick={onClick}>Update Value</Button>
</>
);
};
export default ReadOnly;
我曾尝试将 useEffect 函数监视的值从 formContext
更改为 formContext.queryData[0].basicInformation.firstName
,但没有效果。我也尝试过使用 props
代替。我什至尝试完全删除 watch 数组,希望它只是垃圾邮件更新,但什么也没有。
关于如何实现这一点有什么建议吗?我知道该值正在传递到组件,因为当我按下按钮时它会起作用。当我在网页上的 React 检查器中检查它时,我可以清楚地看到值就在那里。干杯。
编辑:
该组件被用作 react-jsonschema-form 的小部件。基本上,每次更新 formData
时,我都会将其传递回 formContext
。 formContext
是我可以将其他数据获取到该小部件的唯一方法。下面是我正在做的事情的精简版。
const [formDataAndIncludings, setFormDataAndIncludings] = React.useState<any>(null);
ClientRect.useEffect(() => {
...
// Initial loading of formDataAndIncludings
...
}, [])
const onChange = (e: IChangeEvent<any>) => {
const newFormDataAndIncludings = { ...formDataAndIncludings };
newFormDataAndIncludings.queryData[0] = e.formData;
setFormDataAndIncludings(newFormDataAndIncludings);
};
return (
<Form
...
onChange={onChange}
formContext={formDataAndIncludings}
...
/>
)
状态直接在父级 onChange
中发生变化,因此 ReadOnly
组件中的 useEffect 未被触发。
更新你的 onChange
const onChange = (e: IChangeEvent<any>) => {
setFormDataAndIncludings(prev => ({
...prev ,
queryData : [
e.formData,
...prev.queryData.slice(0,1)
]
}))
//const newFormDataAndIncludings = { ...formDataAndIncludings };
//newFormDataAndIncludings.queryData[0] = e.formData;
//setFormDataAndIncludings(newFormDataAndIncludings);
};
照常提供useEffect依赖
React.useEffect(() => {
setValue(firstName());
}, [formContext]);