gpt4 book ai didi

javascript - React useEffect 清理函数意外调用

转载 作者:行者123 更新时间:2023-12-03 13:43:45 28 4
gpt4 key购买 nike

我正在创建一个自定义 Hook 来在表单提交时获取 api,我在 useEffect Hook 内进行 api 调用,并且我有一个 reducer 来处理 Hook 的状态。其中一个状态首先将 trigger 设置为 false,它控制 useEffect 是否执行任何操作,重点是钩子(Hook)返回一个函数,该函数会翻转 trigger 值,该值仅触发 useEffect当你调用这个函数时。问题是在 api 调用期间调用了 useEffect 的清理函数,即使该组件显然仍处于挂载状态。

清理函数似乎被触发,因为我根据之前的值设置了触发器的值,当我将触发器设置为固定值时,清理函数不会被触发打电话但我失去了我的功能

const fetchReducer = (state, action) => {
switch (action.type) {
case 'FETCH_TRIGGER':
return {
...state,
trigger: !state.trigger
}
case 'FETCH_INIT':
return {
...state,
isLoading: true,
isError: false
};
case 'FETCH_SUCCESS':
return {
...state,
isLoading: false,
isError: false,
datas: action.payload,
};
case 'FETCH_FAILURE':
return {
...state,
isLoading: false,
isError: true,
};
default:
throw new Error();
}
}

const useFetchApi = (query, initialData = []) => {
let isCancelled = false;
const [state, dispatch] = useReducer(fetchReducer, {
isLoading: false,
isError: false,
datas: initialData,
trigger: false
});
const triggerFetch = _ => dispatch({ type: 'FETCH_TRIGGER' });
const cancel = _ => { console.log("canceling");isCancelled = true };

useEffect(_ => {
if (!state.trigger)
return;
triggerFetch();
(async _ => {
dispatch({ type: 'FETCH_INIT' });
try {
const datas = await query();
if (!isCancelled) { //isCancelled is true at this point
dispatch({ type: 'FETCH_SUCCESS', payload: datas })
}
} catch (err) {
if (!isCancelled) {
dispatch({ type: 'FETCH_FAILURE', payload: err })
}
}
})();
return cancel;
}, [state.trigger]);
return { ...state, triggerFetch};
}

用法:

function MyComponent () {
const { datas, isLoading, isError, triggerFetch } = useFetchApi(query);
return (
<form onSubmit={event => {event.preventDefault(); triggerFetch()}}>
...

最佳答案

可以在 useEffect 回调内部使用局部变量。感谢@gaearon

https://codesandbox.io/s/k0lm13kwxo

  useEffect(() => {
let ignore = false;

async function fetchData() {
const result = await axios('https://hn.algolia.com/api/v1/search?query=' + query);
if (!ignore) setData(result.data);
}

fetchData();
return () => { ignore = true; }
}, [query]);

关于javascript - React useEffect 清理函数意外调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55376471/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com