• React报错之无法在未挂载的组件上执行React状态更新


    正文从这开始~

    总览

    为了解决"Warning: Can't perform a React state update on an unmounted component" ,可以在你的useEffect钩子中声明一个isMounted布尔值,用来跟踪组件是否被安装。一个组件的状态只有在该组件被挂载时才会被更新。

    import {useState, useEffect} from 'react';
    
    const App = () => {
      const [state, setState] = useState('');
    
      useEffect(() => {
        // 👇️ set isMounted to true
        let isMounted = true;
    
        async function fetchData() {
          const result = await Promise.resolve(['hello', 'world']);
    
          // 👇️ only update state if component is mounted
          if (isMounted) {
            setState(result);
          }
        }
    
        fetchData();
    
        return () => {
          // 👇️ when component unmounts, set isMounted to false
          isMounted = false;
        };
      }, []);
    
      return (
        <div>
          <h2>State: {JSON.stringify(state)}h2>
        div>
      );
    };
    
    export default App;
    

    当我们试图更新一个未挂载的组件的状态时,会出现"无法在未挂载的组件上执行React状态更新"的警告。

    isMounted

    摆脱该警告的直截了当的方式是,在useEffect钩子中使用isMounted布尔值来跟踪组件是否被挂载。

    useEffect中,我们初始化isMounted布尔值为true

    我们的fetchData 函数执行一些异步的任务,最常见的是一个API请求,并根据响应来更新状态。

    然而,需要注意的是,我们只有当isMounted变量被设置为true时,才会更新状态。

    async function fetchData() {
      const result = await Promise.resolve(['hello', 'world']);
    
      // 👇️ only update state if component is mounted
      if (isMounted) {
        setState(result);
      }
    }
    

    这可以帮助我们避免警告,因为如果组件没有挂载,我们就不会更新状态。

    当组件卸载时,从useEffect钩子返回的函数会被调用。

    return () => {
      // 👇️ when component unmounts, set isMounted to false
      isMounted = false;
    };
    

    我们设置isMounted变量为false,表示该组件不再挂载。如果fetchData函数在组件卸载时被调用,if代码块不会执行是因为isMounted设置为false

    async function fetchData() {
      const result = await Promise.resolve(['hello', 'world']);
    
      // 👇️ only update state if component is mounted
      if (isMounted) {
        setState(result);
      }
    }
    

    提取

    如果经常这样做,可以将逻辑提取到可重用的钩子中。

    import {useState, useEffect, useRef} from 'react';
    
    // 👇️ extract logic into reusable hook
    function useIsMounted() {
      const isMounted = useRef(false);
    
      useEffect(() => {
        isMounted.current = true;
    
        return () => {
          isMounted.current = false;
        };
      });
    
      return isMounted;
    }
    
    const App = () => {
      const [state, setState] = useState('');
    
      // 👇️ use hook
      const isMountedRef = useIsMounted();
    
      useEffect(() => {
        async function fetchData() {
          const result = await Promise.resolve(['hello', 'world']);
    
          // 👇️ only update state if component is mounted
          if (isMountedRef.current) {
            setState(result);
          }
        }
    
        fetchData();
      }, [isMountedRef]);
    
      return (
        <div>
          <h2>State: {JSON.stringify(state)}h2>
        div>
      );
    };
    
    export default App;
    

    useRef()钩子可以传递一个初始值作为参数。该钩子返回一个可变的ref对象,其.current属性被初始化为传递的参数。

    我们在useIsMounted钩子中跟踪组件是否被挂载,就像我们直接在组件的useEffect钩子中做的那样。

    需要注意的是,在fetchData函数中,我们必须检查isMountedRef.current 的值,因为ref上的current属性是ref的实际值。

  • 相关阅读:
    数据分析之面试题目汇总(万字解读)
    启航新征程 | 美格智能正式推出GNSS单频定位模组SGM308,赋能行业定位
    uniapp H5生成画布,插入网络图片。下载画布
    学习笔记:机器学习之支持向量机(三、线性支持向量机-软间隔最大化)
    08.OpenWrt-连接wifi网络
    PostgreSQL教程(三十四):服务器管理(十六)之逻辑复制
    详谈Web3与品牌如何推动下一轮牛市
    在AWS上部署一个网站
    OpenHarmony创新赛丨报名倒计时,超强秘籍带你直通大奖!
    2023年G2电站锅炉司炉证考试题库及G2电站锅炉司炉试题解析
  • 原文地址:https://www.cnblogs.com/chuckQu/p/16548811.html