编程崽

登录

一叶在编程苦海沉沦的扁舟之上,我是那只激情自射的崽

useEffect Hook

useEffect Hook

Effect 翻译为「副作用」,是指进行了某些操作后触发的副作用,useEffect 就是给某些操作和变化绑定个副作用的函数,当这些操作和变化发生,触发这个函数,所以它可以看做是「后置执行」

useEffect 可以看做是类组件中的 componentDidMountcomponentDidUpdate componentWillUnmount 这三个钩子的组合。

用法

用法:

js 复制代码
useEffect(Funciton[, Array])
  • Function:将会在合适的时机执行,这个时机的决定权,由第二个入参决定,且 Function 也可以返回一个方法,叫做「清除函数」。
  • Array:监听的变量数组,非必传。

useEffect 可以返回一个方法,下面对useEffect不同写法时的表现进行说明。

1. 不写后面的数组,那么每次组件被重新渲染、更新时,都会执行一次

jsx 复制代码
import React, { useEffect } from 'react';

export default function Test() {
  useEffect(() => {
    // 该处的代码,只有再以下情况时会被执行
    // 1. 该组件初始化时执行一次
    // 2. 该组件被重新渲染时,比如useState创造的变量发生变化时
  })
  return <div></div>
}

2. 后面写一个空数组,那么只有组件第一次被初始化时执行一次,更新时不会执行,相当于vue的mounted

jsx 复制代码
import React, { useEffect } from 'react';

export default function Test() {
  useEffect(() => {
    // 该处的代码,只有在以下情况时会被执行
    // 1. 该组件初始化时执行一次
    // 相当于 Vue 的 mounted
  }, [])
  return <div></div>
}

3. 后面的空数组填写一个或多个变量,那么除了第一次被初始化时执行一次,数组中写入的变量发生变化时也会执行,相当于vue中mounted + watch 的结合

jsx 复制代码
import React, { useState, useEffect } from 'react';

export default function Test() {
  const [num, setNum] = useState(1)

  useEffect(() => {
    // 该处的代码,只有在以下情况时会被执行
    // 1. 该组件初始化时执行一次
    // 2. 数组中写入的变量发生变化时执行
  }, [num])
  return <div onClick={() => setNum(num + 1)}>Number: {num}</div>
}

4. useEffect返回一个方法,这个方法会再useEffect每次执行之前执行一次(除了除了组件初始化时的那次),都会执行一次,可以用作组件销毁时的方法

jsx 复制代码
import React, { useEffect } from 'react';

export default function Test() {
  useEffect(() => {
    // 此处执行的时机不变
    return () => {
      // 该处的代码,只有在以下情况时会被执行
      // 1. useEffect每次执行之前(除了组件初始化时的那次),都会执行一下此处的代码
      // 2. 当前组件被销毁时执行一次
    }
  })
  return <div></div>
}

注意

effect 方法内部的作用域会记录执行时的变量

effect 方法内部的作用域会记录执行时的变量。

比如如下代码,在 state 发生变化后,effect 执行,会在 10秒后打印 state,假设当前 state 的值为1,即使这 10 秒中内,state 的值发生了变化,最终 10 秒后打印时,打印的值仍然是 1。

js 复制代码
React.useEffect(() => {
  setTimeout(() => {
    console.log(state)
  }, 1000 * 10);
}, [state])

尽量不要在 effect 方法中修改 state

在 effect 方法中修改 state 要慎重,因为 effect 本身就是 state 修改时触发,再在内部修改 state,容易造成死循环。