useEffect
useEffect
是 React 中的一个 Hook,用来处理副作用(side effects)。函数组件的主体只应该用来返回组件的 HTML 代码,所有的其他操作(副效应)都必须通过钩子引入。
副作用包括了数据获取、订阅事件、手动操作 DOM 等等,所有这些操作通常不应该直接放在组件的渲染过程中,而是要通过副作用来处理。
useEffect(() => {})
的作用就是在组件中指定一个副效应函数,组件每渲染一次,该函数就执行一次。
🔑 useEffect
基本结构
useEffect
的基本语法是这样的:
useEffect(() => {
// 这里写副作用代码
}, [依赖数组])
- 第一个参数是一个函数,React 会在组件渲染之后执行这个函数。
- 第二个参数是一个数组,用来控制这个副作用的执行时机。
🍭 useEffect
参数
第一个参数是副作用函数,第二个参数是依赖数组,即当这些值发生变化时就调用一次副作用函数。
当依赖数组为空时,表示该函数只会在第一次渲染时执行,之后不会再执行,通常用于初始化任务(如请求数据、订阅事件等)。
例子
useEffect(() => {
console.log('某个值发生了变化!');
}, [someValue]); // 只在 someValue 发生变化时重新执行副作用
🍒 useEffect
的返回值:
useEffect
的返回值是一个可选的清理函数,这个清理函数会在组件卸载时,或者依赖项变化前被执行。
注意这里是先清理再执行!
这样做可以防止内存泄漏或者不必要的重复操作。
useEffect(() => {
const subscription = props.source.subscribe();
return () => {
subscription.unsubscribe();
};
}, [props.source]);
上面例子中,useEffect()在组件加载时订阅了一个事件,并且返回一个清理函数,在组件卸载时取消订阅。
实际使用中,由于副效应函数默认是每次渲染都会执行,所以清理函数不仅会在组件卸载时执行一次,每次副效应函数重新执行之前,也会执行一次,用来清理上一次渲染的副效应。
🥺为什么是先清理再执行呢?
真正的执行逻辑是 React 的内部机制
React 在下一次执行这个 effect 之前,会自动调用上一次 useEffect
返回的那个清理函数。
对于图中这个例子来说,如果在第一次加载未完成时就发起了第二次请求,那么首次请求作用域中的isActive会被置为false,setPosts就不会执行了。