【问题标题】:Can't perform a React state update on an unmounted component with useEffect hook无法使用 useEffect 钩子对未安装的组件执行 React 状态更新
【发布时间】:2020-07-19 12:50:34
【问题描述】:

我有

useEffect(() => {
        setLoading(true);
        axios
            .get(url, {params})
            .then(data => {
                setData(data || []);
                setLoading(false);
            })
            .catch(() => {
                showToast('Load data failed!', 'error');
                setLoading(false);
            });

    }, [params]);

它给了我

警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。

好的,问题不在于如何解决。当我在axios promise 之后使用 setLoading(false) 时,它工作正常,但在 promise 内部(例如上面)它总是给我警告。其实我想知道为什么会这样?有没有人可以简单地向我解释一下上面的代码流(上面的代码如何与警告一起工作的过程),并可能给出一些使用钩子的最佳实践。

【问题讨论】:

  • 合并这2个集合更新... setData(data || []); setLoading(false);
  • @xdeepakv 好的,但你能解释一下为什么上面的代码会出现警告吗?
  • 你能发布整个文件(包括你正在渲染的组件)吗?此错误可能意味着您的组件在您收到响应之前已被删除

标签: javascript reactjs axios react-hooks use-effect


【解决方案1】:

你需要清理功能。 这意味着您应该调用 useEffect 函数的函数结束。 当依赖项发生变化时(以参数为例)调用该函数。 所以我们可以控制组件何时挂载/卸载

useEffect(() => {
  let cancelled = false;
  setLoading(false);
  async function fetchData() {
    try {
      const response = await axios.get(url, { params });
      if (!cancelled) {
        setData(response.data);
        setLoading(false);
      }
    } catch (e) {
      if (!cancelled) {
        showToast(e.message, "error");
        setLoading(false);
      }
    }
  }
  fetchData();
  // clean up here
  return () => {
    cancelled = true;
  };
}, [params]);

为什么会这样?

假设您的请求很慢,并且当异步请求完成时组件已经卸载。这次抛出这个警告

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
  • 2022-01-18
  • 2019-10-19
  • 2019-07-24
  • 2021-12-03
  • 1970-01-01
相关资源
最近更新 更多