【问题标题】:Why are React props not updated in event handler为什么 React 道具没有在事件处理程序中更新
【发布时间】:2021-09-29 08:53:09
【问题描述】:

我有一个使用 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});
    }
  };

【问题讨论】:

  • 好吧,我使用 React.useRef 完成了这项工作,我认为这是正确的方法,但会让别人告诉我一些不同的事情

标签: reactjs react-functional-component


【解决方案1】:

通过将 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 这么大,你可以只将文件逻辑分离到一个新函数中,然后像这样在钩子中调用它:

  useEffect(() => {
    const onSave = () => {
      saveFile(reactFlowInstance, modelName)
    };
    // ... handlers go here
  }, [reactFlowInstance, modelName]);

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-30
    • 2021-08-20
    • 2016-12-28
    • 2017-04-29
    • 1970-01-01
    相关资源
    最近更新 更多