React Hooks:从 useEffect() 内部引用存储在上下文中的数据

React Hooks: Referencing data that is stored inside context from inside useEffect()

我的上下文中存储了一个大的 JSON blob,然后我可以使用 jsonpath (https://www.npmjs.com/package/jsonpath)

进行引用

我如何才能从 useEffect() 内部访问上下文,而不必将我的上下文变量添加为依赖项(上下文在应用程序的其他位置更新)?

export default function JsonRpc({ task, dispatch }) {
  const { data } = useContext(DataContext);
  const [fetchData, setFetchData] = useState(null);

  useEffect(() => {
    task.keys.forEach(key => {
      let val = jp.query(data, key.key)[0];
      jp.value(task.payload, key.result_key, val);
    });
    let newPayload = {
      jsonrpc: "2.0",
      method: "call",
      params: task.payload,
      id: "1"
    };

    const domain = process.env.REACT_APP_WF_SERVER;
    let params = {};
    if (task.method === "GET") {
      params = newPayload;
    }
    const domain_params =
      JSON.parse(localStorage.getItem("domain_params")) || [];
    domain_params.forEach(e => {
      if (e.domain === domain) {
        params[e.param] = e.value;
      }
    });
    setFetchData({ ...task, payload: newPayload, params: params });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [task]);

}

由于代码原因,我需要 post 一个答案,但我不能 100% 确定你需要什么,所以我会根据你的反馈建立一个正确的答案:)

所以,我的第一个想法是:你不能把你的效果分成两个 React.useEffect 吗?像这样:

export default function JsonRpc({ task, dispatch }) {
  ...

  useEffect(() => {
    ...
    setFetchData(...);
  }, [task]);


  useEffect(() => {
    ...
  }, [data]);

   .. 
}

现在,如果我的理解是正确的,这是事件时间线的示例:

  1. 由于 task 的更新,您将触发第一个 useEffect,它可以 setFetchData();
  2. 由于 fetchData 上的更新,并且进行了 AXIOS 调用,这会更新 data(上下文中的 属性);
  3. 此时,您输入第二个 useEffect,其中您有更新的 data,但是 NO 调用 setFetchData(),因此没有循环;

然后,如果你想(但不能)将 data 放入你的 useEffect 的依赖数组中,我可以想象我写的两个 useEffect 有一些共享代码: 你可以编写一个由 useEffect 调用的通用方法, 但是 重要的是 setFetchData() 调用在这个通用方法之外。

如果您需要更多说明,请告诉我。

感谢@Jolly 的回复!我找到了解决方法:

我将数据查找移动到状态初始计算:

const [fetchData] = useState(processFetchData(task, data));

然后我只是确保在调用 axios 后通过执行从父组件传递给组件的完整函数来清除组件。

这暂时有效,但如果您有任何其他建议,我很乐意听取!