为什么 React props 没有在事件处理程序中更新
Why are React props not updated in event handler
我有一个使用 useEffect 挂钩订阅外部事件的功能组件,并且该外部事件正在使用组件属性中的值。我不明白为什么组件本身在渲染时使用更新的 prop 值,但我的回调使用原始值。
我想也许我需要更改 useEffect 的第二个参数来指定道具,但这没有任何区别。
在下面的示例中,onSave 回调被调用并尝试使用 props.modelName 的当前值,但是,即使组件本身具有更新的值回调似乎只能看到 属性.
的原始值
这是为什么?它与关闭有关还是我遗漏了其他东西?
useEffect(() => {
EventBus.on(EventIds._designerSaveCommand, onSave);
return () => {
EventBus.remove(EventIds._designerSaveCommand, onSave);
};
}, [reactFlowInstance,props]);
我的事件处理程序是这样的:
const onSave = () => {
try {
const object = reactFlowInstance?.toObject();
if(object) {
const exportedModel: IExportedModel = {
modelName: props.modelName, <---- This is not the current value in the component props
model: object
};
const json = JSON.stringify(exportedModel);
var blob = new Blob([json], { type: "application/json" });
FileSaver.saveAs(blob, `${props.modelName}.json`);
}
}
catch(e) {
setMessage({text: e.message, type: MessageBarType.error});
}
};
你的想法是正确的,将 prop 添加到依赖项数组。您还需要将函数 onSave()
移动到钩子内部。然后它将引用最新的 modelName
.
useEffect(() => {
const onSave = () => {
try {
const object = reactFlowInstance?.toObject();
if(object) {
const exportedModel: IExportedModel = {
modelName: modelName,
model: object
};
const json = JSON.stringify(exportedModel);
var blob = new Blob([json], { type: "application/json" });
FileSaver.saveAs(blob, `${modelName}.json`);
}
}
catch(e) {
setMessage({text: e.message, type: MessageBarType.error});
}
};
EventBus.on(EventIds._designerSaveCommand, onSave);
return () => {
EventBus.remove(EventIds._designerSaveCommand, onSave);
};
}, [reactFlowInstance, modelName]);
如果你不喜欢 useEffect
这么大,你可以只将文件逻辑分离到一个新函数中,然后像这样在 hook 中调用它:
useEffect(() => {
const onSave = () => {
saveFile(reactFlowInstance, modelName)
};
// ... handlers go here
}, [reactFlowInstance, modelName]);
我有一个使用 useEffect 挂钩订阅外部事件的功能组件,并且该外部事件正在使用组件属性中的值。我不明白为什么组件本身在渲染时使用更新的 prop 值,但我的回调使用原始值。
我想也许我需要更改 useEffect 的第二个参数来指定道具,但这没有任何区别。
在下面的示例中,onSave 回调被调用并尝试使用 props.modelName 的当前值,但是,即使组件本身具有更新的值回调似乎只能看到 属性.
的原始值这是为什么?它与关闭有关还是我遗漏了其他东西?
useEffect(() => {
EventBus.on(EventIds._designerSaveCommand, onSave);
return () => {
EventBus.remove(EventIds._designerSaveCommand, onSave);
};
}, [reactFlowInstance,props]);
我的事件处理程序是这样的:
const onSave = () => {
try {
const object = reactFlowInstance?.toObject();
if(object) {
const exportedModel: IExportedModel = {
modelName: props.modelName, <---- This is not the current value in the component props
model: object
};
const json = JSON.stringify(exportedModel);
var blob = new Blob([json], { type: "application/json" });
FileSaver.saveAs(blob, `${props.modelName}.json`);
}
}
catch(e) {
setMessage({text: e.message, type: MessageBarType.error});
}
};
你的想法是正确的,将 prop 添加到依赖项数组。您还需要将函数 onSave()
移动到钩子内部。然后它将引用最新的 modelName
.
useEffect(() => {
const onSave = () => {
try {
const object = reactFlowInstance?.toObject();
if(object) {
const exportedModel: IExportedModel = {
modelName: modelName,
model: object
};
const json = JSON.stringify(exportedModel);
var blob = new Blob([json], { type: "application/json" });
FileSaver.saveAs(blob, `${modelName}.json`);
}
}
catch(e) {
setMessage({text: e.message, type: MessageBarType.error});
}
};
EventBus.on(EventIds._designerSaveCommand, onSave);
return () => {
EventBus.remove(EventIds._designerSaveCommand, onSave);
};
}, [reactFlowInstance, modelName]);
如果你不喜欢 useEffect
这么大,你可以只将文件逻辑分离到一个新函数中,然后像这样在 hook 中调用它:
useEffect(() => {
const onSave = () => {
saveFile(reactFlowInstance, modelName)
};
// ... handlers go here
}, [reactFlowInstance, modelName]);