useEffect有依赖项和没有依赖项时return内外的代码执行顺序

​一、useEffect的基本用法

  1. useEffect 接收两个参数,第一个参数是 Effect 函数;第二个参数是一个数组,避免 effects 不必要的重复调用;
  2. useEffect 第二个参数用于定义所依赖的变量,若传空数组,也就是没有依赖变化的项,只用会在页面初始化时调用一次, 若添加依赖项,依赖数组中变量之一更改,即会触发运行;
  3. 第二个参数不存在的时候,每次页面更新都会执行该 useEffect的第一个参数函数;
    例如:
import React,{useEffect,useState} from 'react'

function Demo () {
  const [count,setCount]=useState(0)
  useEffect(() => { 
    console.log('无依赖---------------------------',count)
  })
  useEffect(() => { 
    console.log('依赖为[]------------------------',count)
  },[])
  useEffect(() => { 
    console.log('依赖为[count]------------------------',count)
  },[count])
  return (
    <div>
      <p>count的值为: {count} </p>
      <button onClick={()=>setCount(count+1)}>add</button>
    </div>
  )
}

export default Demo

初始化执行结果:

无依赖--------------------------- 0
About.tsx:9 依赖为[]------------------------ 0
About.tsx:12 依赖为[count]------------------------ 0

点击add后的结果:

无依赖--------------------------- 1
About.tsx:12 依赖为[count]------------------------ 1

二、useEffect内return一个函数

为了更好的理解,我们先看结果再总结,先看示例补充:

import React,{useEffect,useState} from 'react'

function Demo () {
  const [count,setCount]=useState(0)
  useEffect(() => { 
    console.log('无依赖---------------------------', count)
    return () => {
      console.log('执行  无依赖  时的return的函数')
    }
  })
  useEffect(() => { 
    console.log('依赖为[]------------------------', count)
    return () => {
      console.log('执行 依赖为[]  时的return的函数')
    }
  },[])
  useEffect(() => { 
    console.log('依赖为[count]------------------------', count)
    return () => {
      console.log('执行 依赖为[count]  时的return的函数')
    }
  },[count])
  return (
    <div>
      <p>count的值为: {count} </p>
      <button onClick={()=>setCount(count+1)}>add</button>
    </div>
  )
}

export default Demo

1. 初始化时控制台打印结果:

无依赖--------------------------- 0
依赖为[]------------------------ 0
依赖为[count]------------------------ 0
执行  无依赖  时的return的函数
执行 依赖为[]  时的return的函数
执行 依赖为[count]  时的return的函数
无依赖--------------------------- 0
依赖为[]------------------------ 0
依赖为[count]------------------------ 0

useEffect有依赖项和没有依赖项时return内外的代码执行顺序_第1张图片

可以看到初始化时每个useEffect内函数执行了两次,因为我使用的是 React 18, React 18在 并发模式下会强制让组件更新一次,每一个return的函数也在强制更新时执行了一次。相当于执行了如下操作:挂载组件----移除组件–重新挂载组件。如果是React 17 ,只会挂载一次,其打印结果为:

无依赖--------------------------- 0
依赖为[]------------------------ 0
依赖为[count]------------------------ 0

2. 点击add按钮之后的控制台打印结果:

执行  无依赖  时的return的函数
执行 依赖为[count]  时的return的函数
无依赖--------------------------- 1
依赖为[count]------------------------ 1

useEffect有依赖项和没有依赖项时return内外的代码执行顺序_第2张图片

此时更新的变量时count,所以监听了count的useEffect都执行了,没有第二个参数的useEffect也执行了,每次都是先执行return的函数,再去执行return外面的部分。

3. 切换到其他页面时(也就是移除组件)控制台打印结果:

执行  无依赖  时的return的函数
执行 依赖为[]  时的return的函数
执行 依赖为[count]  时的return的函数

此时按照useEffect的顺序依次执行力其内的return部分

总结:

  • 无依赖项时,首次加载会执行useEffect第一个参数函数的return外的部分,每次更新时会先执行return内部分,再执行return外的部分。
  • 依赖项为空数组([])时,会在页面首次加载时运行useEffect 第一个参数的那个函数,类似于执行componentDidMount,且只执行一遍,函数内return 的函数会在页面即将销毁时或移除组件时执行,类似于执行componentWillUnMount
  • 依赖项不为空时,首次加载会执行useEffect第一个参数函数的return外的部分,每次依赖项更新时会先执行return内部分,再执行return外的部分。

也就是说,除了初次挂载和移除组件时会单独执行return外和return内的函数,其余更新的时候都会依次执行return内再执行return外的部分。

你可能感兴趣的:(javascript,前端,react.js)