She*_*ixt 1 javascript reactjs axios
在 React 功能组件中取消异步请求的正确方法是什么?
我有一个脚本,它在加载时(或在某些用户操作下)从 API 请求数据,但如果这是正在执行的过程中并且用户导航离开,则会导致以下警告:
警告:无法对卸载的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 useEffect 清理函数中的所有订阅和异步任务。
我读过的大部分内容都使用基于类的组件AbortController的componentDidUnmount方法解决了这个问题。而我的 React 应用程序中有一个功能组件,它使用 Axois 向 API 发出异步数据请求。
该函数驻留在useEffect功能组件中的钩子中,以确保在组件呈现时运行该函数:
useEffect(() => {
loadFields();
}, [loadFields]);
Run Code Online (Sandbox Code Playgroud)
这是它调用的函数:
const loadFields = useCallback(async () => {
setIsLoading(true);
try {
await fetchFields(
fieldsDispatch,
user.client.id,
user.token,
user.client.directory
);
setVisibility(settingsDispatch, user.client.id, user.settings);
setIsLoading(false);
} catch (error) {
setIsLoading(false);
}
}, [
fieldsDispatch,
user.client.id,
user.token,
user.client.directory,
settingsDispatch,
user.settings,
]);
Run Code Online (Sandbox Code Playgroud)
这是触发的 axios 请求:
async function fetchFields(dispatch, clientId, token, folder) {
try {
const response = await api.get(clientId + "/fields", {
headers: { Authorization: "Bearer " + token },
});
// do something with the response
} catch (e) {
handleRequestError(e, "Failed fetching fields: ");
}
}
Run Code Online (Sandbox Code Playgroud)
注意:api变量是对axios.create对象的引用。
取消fetch操作axios:
广告 1.)
axios 自带取消 API:
const source = axios.CancelToken.source();
axios.get('/user/12345', { cancelToken: source.token })
source.cancel(); // invoke to cancel request
Run Code Online (Sandbox Code Playgroud)
您可以通过停止不再需要的异步请求来使用它来优化性能。使用本机浏览器fetchAPI,AbortController将改为使用。
广告 2.)
这将停止警告"Warning: Can't perform a React state update on an unmounted component."。例如,您不能调用setState已经卸载的组件。这是一个 Hook 强制和封装上述约束的示例。
useAxiosFetch我们可以将这两个步骤合并到自定义 Hook 中:
function useAxiosFetch(url, { onFetched, onError, onCanceled }) {
React.useEffect(() => {
const source = axios.CancelToken.source();
let isMounted = true;
axios
.get(url, { cancelToken: source.token })
.then(res => { if (isMounted) onFetched(res); })
.catch(err => {
if (!isMounted) return; // comp already unmounted, nothing to do
if (axios.isCancel(err)) onCanceled(err);
else onError(err);
});
return () => {
isMounted = false;
source.cancel();
};
}, [url, onFetched, onError, onCanceled]);
}
Run Code Online (Sandbox Code Playgroud)
const source = axios.CancelToken.source();
axios.get('/user/12345', { cancelToken: source.token })
source.cancel(); // invoke to cancel request
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4510 次 |
| 最近记录: |