登录
Effect 翻译为「副作用」,是指进行了某些操作后触发的副作用,useEffect 就是给某些操作和变化绑定个副作用的函数,当这些操作和变化发生,触发这个函数,所以它可以看做是「后置执行」
useEffect 可以看做是类组件中的 componentDidMount
、componentDidUpdate
和 componentWillUnmount
这三个钩子的组合。
用法:
useEffect(Funciton[, Array])
useEffect
可以返回一个方法,下面对useEffect
不同写法时的表现进行说明。
1. 不写后面的数组,那么每次组件被重新渲染、更新时,都会执行一次
import React, { useEffect } from 'react';
export default function Test() {
useEffect(() => {
// 该处的代码,只有再以下情况时会被执行
// 1. 该组件初始化时执行一次
// 2. 该组件被重新渲染时,比如useState创造的变量发生变化时
})
return <div></div>
}
2. 后面写一个空数组,那么只有组件第一次被初始化时执行一次,更新时不会执行,相当于vue的mounted
import React, { useEffect } from 'react';
export default function Test() {
useEffect(() => {
// 该处的代码,只有在以下情况时会被执行
// 1. 该组件初始化时执行一次
// 相当于 Vue 的 mounted
}, [])
return <div></div>
}
3. 后面的空数组填写一个或多个变量,那么除了第一次被初始化时执行一次,数组中写入的变量发生变化时也会执行,相当于vue中mounted + watch 的结合
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每次执行之前执行一次(除了除了组件初始化时的那次),都会执行一次,可以用作组件销毁时的方法
import React, { useEffect } from 'react';
export default function Test() {
useEffect(() => {
// 此处执行的时机不变
return () => {
// 该处的代码,只有在以下情况时会被执行
// 1. useEffect每次执行之前(除了组件初始化时的那次),都会执行一下此处的代码
// 2. 当前组件被销毁时执行一次
}
})
return <div></div>
}
effect 方法内部的作用域会记录执行时的变量。
比如如下代码,在 state 发生变化后,effect 执行,会在 10秒后打印 state,假设当前 state 的值为1,即使这 10 秒中内,state 的值发生了变化,最终 10 秒后打印时,打印的值仍然是 1。
React.useEffect(() => {
setTimeout(() => {
console.log(state)
}, 1000 * 10);
}, [state])
在 effect 方法中修改 state 要慎重,因为 effect 本身就是 state 修改时触发,再在内部修改 state,容易造成死循环。