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]);
..
}
现在,如果我的理解是正确的,这是事件时间线的示例:
- 由于
task
的更新,您将触发第一个 useEffect
,它可以 setFetchData()
;
- 由于
fetchData
上的更新,并且进行了 AXIOS 调用,这会更新 data
(上下文中的 属性);
- 此时,您输入第二个
useEffect
,其中您有更新的 data
,但是 NO 调用 setFetchData()
,因此没有循环;
然后,如果你想(但不能)将 data
放入你的 useEffect
的依赖数组中,我可以想象我写的两个 useEffect
有一些共享代码: 你可以编写一个由 useEffect
调用的通用方法, 但是 重要的是 setFetchData()
调用在这个通用方法之外。
如果您需要更多说明,请告诉我。
感谢@Jolly 的回复!我找到了解决方法:
我将数据查找移动到状态初始计算:
const [fetchData] = useState(processFetchData(task, data));
然后我只是确保在调用 axios 后通过执行从父组件传递给组件的完整函数来清除组件。
这暂时有效,但如果您有任何其他建议,我很乐意听取!
我的上下文中存储了一个大的 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]);
..
}
现在,如果我的理解是正确的,这是事件时间线的示例:
- 由于
task
的更新,您将触发第一个useEffect
,它可以setFetchData()
; - 由于
fetchData
上的更新,并且进行了 AXIOS 调用,这会更新data
(上下文中的 属性); - 此时,您输入第二个
useEffect
,其中您有更新的data
,但是 NO 调用setFetchData()
,因此没有循环;
然后,如果你想(但不能)将 data
放入你的 useEffect
的依赖数组中,我可以想象我写的两个 useEffect
有一些共享代码: 你可以编写一个由 useEffect
调用的通用方法, 但是 重要的是 setFetchData()
调用在这个通用方法之外。
如果您需要更多说明,请告诉我。
感谢@Jolly 的回复!我找到了解决方法:
我将数据查找移动到状态初始计算:
const [fetchData] = useState(processFetchData(task, data));
然后我只是确保在调用 axios 后通过执行从父组件传递给组件的完整函数来清除组件。
这暂时有效,但如果您有任何其他建议,我很乐意听取!