1、概述
useEffect
是React
中一个用于 将组件与外部系统同步的 Hook
;在函数式组件中处理副作用函数的 Hook,用于替代类式组件中的生命周期函数;
可以在副作用函数中 实现以下操作:
a、请求接口,获取后台提供数据
b、操作DOM;
c、事件监听;window.addEventListener()
d、清理任务; clearInterval()
如果没有与外部系统链接,或许可以不使用 useEffect
2、写法
useEffect(fnc, dependencies)
第一个参数:fnc
是一个副作用函数,即在执行的过程中会影响组件的其他属性,而不是纯函数
,纯函数是没有参数,输入相同的时候,输出也是相同的;
第二个参数:可选参数
:dependencies 是副作用函数执行的依赖项数组
,可以是空数组,a/当为空数组时候,组件只会在初次渲染的时候,触发副作用函数执行;b/当不传依赖项时候,每次组件渲染都会触发副作用函数执行;c/依赖项可以是 props、state
当:fnc 中 return () => {}
时,这里执行的是组件卸载时候
的逻辑;
2.1、依赖项不传
每次渲染都会触发副作用函数, 类似于类式组件中的 componentDidUpdate
钩子
useEffect(() => {
console.log('==视图更新了=')
})
2.2、依赖项传入空数组
只有在第一次挂载时候才会触发副作用函数,类似于类式组件中 componentDidMount
钩子
useEffect(() => {
console.log('=只有挂载=更新了=')
}, [])
2.3、依赖指定属性时
当属性 name 变化时候,就会触发副作用函数,类似于类式组件中的 componentDidUpdate
钩子
const [name, setName] = useState('Andy')
useEffect(() => {
console.log('=只有name 属性变化时=更新了=')
},[name])
2.4、副作用函数中传入 回调函数时
此时,类似于 类式组件中 componentWillUnmount
钩子
可以在这里清除定时任务,销毁DOM结构、移除事件监听
useEffect(() => {
return () => {
console.log('====组件将要卸载了=')
}
}, [name])
2.5、清除定时任务
import { useEffect, useState } from 'react'
export default function index() {
const [count, setCount] = useState(0)
const [name, setName] = useState('Andy')
const handleChangeName = () => {
setName(`${name} + &`)
}
let timer = null
const handleChangeTime = () => {
console.log('==开始计数了=')
timer = setInterval(() => {
setCount((count) => count + 1)
}, 500)
}
useEffect(() => {
return () => {
// 清除定时任务
clearInterval(timer)
console.log('==计数结束了=')
}
}, [name])
return (
<div>
<h3>useEffect text demo .</h3>
<p>名称:{name}</p>
<button onClick={handleChangeName}>清除定时任务</button>
<hr />
<p>计数器:{count}</p>
<button onClick={handleChangeTime}>计时开始</button>
</div>
)
}
2.6、清除事件监听
useEffect(() => {
// 组件挂载 监听视图窗口变化
const resize = () => console.log('窗口大小变化');
window.addEventListener('resize', resize);
return() => {
window.removeEventListener('resize', resize)
}
}, [])
2.7、死循环
禁止
在 useEffect
中使用 useState 的SetXxx
函数, 更新useEffect 中的依赖项;
否则会导致进入死循环
useEffect(() => {
// 死循环
const timer = setInterval(() => {
console.log('==计数进行中=', count, count)
setCount(count + 1)
}, 500)
return () => {
clearInterval(timer)
console.log('==计数结束了=')
}
},[count, name])
3、注意事项:
1、依赖项为引用类型时,React 会对比前后地址(引用指针)
是否一致,如果一致 Effect 则不会重新渲染;
2、避免使用更新依赖时产生死循环;
3、组件中使用的定时任务,需要在组件卸载时候清除,避免导致内存溢出;
4、依赖项避免过多,会导致追踪复杂化,或者出现意向不到的问题,尽量简化依赖项;
4、useEffect
与 useMemo
的区域
useMemo
主要用于计算和缓存值
,以减少重复昂贵的计算
,它返回一个 memoized
值。
useEffect
主要用于处理副作用,例如订阅、数据获取、DOM 操作等,它不返回值,但可以在组件渲染后执行操作。
useMemo
的作用是优化性能,减少不必要的计算,即使没有useMemo
组件同样可以正常执行。
useEffect
的目标是处理副作用,管理组件的生命周期
。
useMemo 的依赖数组用于控制何时重新计算值
,
而 useEffect
的依赖数组用于控制何时运行副作用函数。