• React Hooks


    useEffect()

    useEffectReact中的一个钩子函数,用于处理副作用操作。副作用是指在组件渲染过程中,可能会对外部环境产生影响的操作,比如数据获取、订阅事件、操作DOM等。
    useEffect接受两个参数:一个是副作用函数,另一个是依赖数组。

    useEffect(() => {
      // 副作用函数
      // 在组件渲染时执行
      // 可以进行副作用操作
    }, [依赖数组]);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    二个参数的传值有以下几种情况,决定页面render的时机,dom操作

    1、不传递

    useEffect不传递第二个参数会导致每次渲染都会运行useEffect。然后,当它运行时,它获取数据并更新状态。然后,一旦状态更新,组件将重新呈现,这将再次触发useEffect,通常我们是不希望它一直刷新的。

    useEffect(()=>{
        console.log(props.number)
        setNumber(props.number)
    }) //所有更新都执行
    
    • 1
    • 2
    • 3
    • 4

    2、传递空数组

    //仅在挂载和卸载的时候执行

    useEffect(()=>{
      console.log(props)
    },[]) 
    
    • 1
    • 2
    • 3

    3、传递一个值

    //count更新时执行

    useEffect(()=>{
      console.log(count)
    },[count]) 
    
    • 1
    • 2
    • 3

    4、传递多个

    //监听props对象number的更改

    const Asynchronous : React.FC=({number})=>{
        const [number2,setNumber2] = useState(number);
        useEffect(()=>{
            console.log(number)
            setNumber2(number)
        },[number,setNumber2]) //监听props对象number的更改
        //setNumber2是useState返回的setter,所以不会在每次渲染时重新创建它,因此effect只会运行一次
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5、传递props的对象 传递的useState返回的setter

    6、return 方法

    // 组件销毁的时候、用来取消订阅、清除定时器

    const timer = setInterval(() => {
    	setCount(count + 1)
    }, 1000)
    // useEffect方法的第一个参数是一个函数,函数可以return一个方法,这个方法就是在组件销毁的时候会被调用
    useEffect(() => {
        return () => {
            clearInterval(timer)
        }
    }, [])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    7、异步操作

    // 刚进入界面进行数据请求,不过常在componentDidMount中加载数据
    // 副作用函数可以是一个异步函数,可以在其中进行异步操作,比如数据获取

    useEffect(() => {
      const fetchData = async () => {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        console.log(data);
      };
    
      fetchData();
    }, []);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    8.useEffect监测不到依赖数组元素的变化多种情况?

    1. 依赖数组元素是一个对象或数组:useEffect使用浅层比较来判断依赖数组元素是否发生变化。如果依赖数组中的元素是一个对象或数组,只有当引用发生变化时,useEffect才会重新执行。如果您修改了对象或数组的属性,但是引用没有发生变化,useEffect无法感知到这个变化。
    const [data, setData] = useState({ name: 'John' });
    
    // 错误示例:修改对象属性,但引用未变化
    setData({ ...data, age: 20 }); // useEffect无法感知到属性的变化
    
    // 正确示例:修改对象属性,引用发生变化
    setData(prevData => ({ ...prevData, age: 20 })); // useEffect会感知到属性的变化
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 依赖数组元素是一个闭包变量:如果依赖数组中的元素是一个闭包变量,那么在每次渲染时,useEffect都会获取到最新的闭包变量。因此,即使闭包变量的值发生了变化,useEffect也无法感知到这个变化。
    const [count, setCount] = useState(0);
    
    // 闭包变量 错误示例
    const handleClick = () => {
      setCount(count + 1);
    };
    // 函数式更新 可以被监听变化
    const handleClick = () => {
      setCount(prevCount => prevCount + 1);
    };
    
    useEffect(() => {
      console.log(count); // 每次渲染都会获取最新的count值
    }, [count]); // 无法感知到闭包变量的变化
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 依赖数组元素是一个函数:如果依赖数组中的元素是一个函数,那么useEffect会在每次渲染时都认为该函数发生了变化,从而重新执行副作用函数。
    const [count, setCount] = useState(0);
    
    const handleClick = () => {
      setCount(count + 1);
    };
    
    // 错误示例:将函数作为依赖数组元素
    useEffect(() => {
      console.log(count);
    }, [handleClick]); // 每次渲染都会重新执行副作用函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    // 如果您希望避免在每次渲染时都重新执行副作用函数,可以将函数定义在useEffect的外部,并在副作用函数中引用该函数.

    const [count, setCount] = useState(0);
    
    const handleClick = () => {
      setCount(count + 1);
    };
    
    // 正确示例:在副作用函数中引用函数
    useEffect(() => {
      const handleEffect = () => {
        console.log(count);
      };
    
      handleEffect();
    }, [count]); // 只在count发生变化时执行副作用函数
    
    // 或者使用useCallback包裹函数
    const handleEffect = useCallback(() => {
      console.log(count);
    }, [count]);
    
    useEffect(() => {
      handleEffect();
    }, [handleEffect]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    盘点Go中的开发神器
    (附源码)springboot投稿和稿件处理系统 毕业设计 201458
    发布首批三款纯电车型 捷尼赛思2025年起转向全面电动车
    Asynchronous Servlet 在 Nacos 1.X 动态配置管理中的应用
    诙谐有趣的《UVM实战》笔记——第二章 一个简单的UVM验证平台
    所有企业都得做私域吗?做私域有“快捷”方式呢?
    【遥控器开发基础教程1】疯壳·开源编队无人机-GPIO(遥控器指示灯控制)
    【活动】CSDN诚邀您参与回归创作
    使用单元测试提高代码质量与可维护性
    【吴恩达机器学习笔记】二、单变量线性回归
  • 原文地址:https://blog.csdn.net/qq_30109365/article/details/134425239