乐闻世界logo
搜索文章和话题

How to cancel a fetch on componentWillUnmount

4 个月前提问
3 个月前修改
浏览次数29

1个答案

1

在 React 中,组件在其生命周期内可能会发起接口请求,比如通过 AJAX 来获取数据。这些请求如果在组件卸载(unmount)时还未完成,就可能导致内存泄露或者设置已经被卸载组件的状态,从而引发错误。

为了避免这种情况,我们可以在组件卸载时取消这些未完成的请求。以下是几种常用的方法来实现这一点:

使用 AbortController (推荐用于 Fetch API)

AbortController 是一个原生 JavaScript API,可以用来取消一个或多个 Web 请求。这个方法特别适用于使用 Fetch API 发起的请求。

示例代码

jsx
import React, { useEffect } from 'react'; function MyComponent() { useEffect(() => { const controller = new AbortController(); const signal = controller.signal; fetch('https://api.example.com/data', { signal }) .then(response => response.json()) .then(data => { // 处理数据 }) .catch(error => { if (error.name === 'AbortError') { console.log('Fetch aborted'); } else { console.error('Fetch error:', error); } }); return () => { controller.abort(); }; }, []); return <div>Component Content</div>; }

在这个例子中,我们创建了一个AbortController实例,并从中获取一个signal对象,将其作为选项传递给fetch。这样,当我们调用controller.abort()时,所有使用该signal的请求都会被取消。

使用 Axios 的取消令牌

如果你使用 Axios 来发起 HTTP 请求,Axios 提供了取消请求的功能,通过使用取消令牌(cancel token)。

示例代码

jsx
import React, { useEffect } from 'react'; import axios from 'axios'; function MyComponent() { useEffect(() => { const CancelToken = axios.CancelToken; const source = CancelToken.source(); axios.get('https://api.example.com/data', { cancelToken: source.token }).then(response => { // 处理数据 }).catch(function (thrown) { if (axios.isCancel(thrown)) { console.log('Request canceled', thrown.message); } else { console.error('Request failed', thrown); } }); return () => { source.cancel('Component unmounting, operation canceled'); }; }, []); return <div>Component Content</div>; }

在这个例子中,我们使用axios.CancelToken.source()创建了一个取消令牌,并通过请求的配置传递这个令牌。当组件卸载时,调用source.cancel()方法来取消请求。

小结

使用这些策略可以有效避免组件卸载时导致的内存泄漏和错误。选择适合你当前使用的 API 的方法,并在组件卸载时正确清理资源。

2024年6月29日 12:07 回复

你的答案