【问题标题】:Cancel async fetch request in React Native using Expo使用 Expo 取消 React Native 中的异步获取请求
【发布时间】:2020-02-19 12:31:42
【问题描述】:

我有一个使用 Expo (v35.0.0) 构建的 React Native 应用程序。我有一个简单的异步函数 (loadData()),它对 API 运行 fetch(通过 fetchData())请求,然后将响应传递到我的 redux 存储中:

const loadData = async (id, token) => {
  setIsLoading(true);
  try {
    await dispatch(fetchData(id, token));
  } catch (error) {
    setHasError(true);
  }
  setIsLoading(false);
};

useEffect(() => {
  loadData(user.client.id, user.token);
}, [user.client.id]);

但是,当用户注销时,我们会看到警告:“无法在未安装的组件上执行 React 状态更新”,我理解这是因为异步请求已被取消。

我已尝试实施AbortController 方法(如本文所述:https://dev.to/iquirino/react-hook-clean-up-useeffect-24e7),但随后出现错误,指出AbortConroller 未知。

我认为对 AbortConroller 的支持现在将在 Expo 中,因为它作为 v0.60 版本的一部分于去年 7 月被添加到 React Native。

那么,是否可以在 Expo 中实现AbortController 来取消异步请求?如果没有,我应该如何取消请求以避免警告(和内存泄漏)?

【问题讨论】:

  • 在你的useEffect钩子里,你可以返回一个清理函数,用这个你可以设置一个标志,然后如果它被设置了abort而不是调用setState..

标签: javascript reactjs react-native fetch expo


【解决方案1】:

因为您的dispatch 是异步的,所以它可能会在您的组件卸载后完成。

useEffect 中,您可以返回一个调用清理的函数。在这里你可以设置一个标志来表示组件不再挂载,如果这个标志表示它不再挂载,你可以告诉它不要更新状态。

例如。

let mounted = true;

const loadData = async (id, token) => {
  setIsLoading(true);
  try {
    await dispatch(fetchData(id, token));
  } catch (error) {
    if (mounted) setHasError(true);
  }
  if (mounted) setIsLoading(false);
};

useEffect(() => {
  loadData(user.client.id, user.token);
  return () => mounted = false;
}, [user.client.id]);

【讨论】:

  • 太棒了,谢谢@Keith。仍然有兴趣知道为什么 AbortController 在 Expo 中无法运行,但这解决了我的问题。
猜你喜欢
  • 2021-07-02
  • 2017-10-05
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 1970-01-01
  • 2016-01-11
  • 1970-01-01
相关资源
最近更新 更多