这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战
Effect Hook
函数是确定的,输入什么东西,对应输出什么东西。
但是还有很多不确定的东西,网络请求,dom操作等,这些统称为副作用side effect。
React中有两种常见副作用
- 无需清除的副作用
- 发送网络请求,手动请求,记录日志等。
- 需要清除的副作用
在class组件中,如果你想要实现在页面挂载完执行,和每次更新时执行需要用到两个生命周期函数(componentDidMount,componentDidUpdate)
useEffect
::在首次挂载时执行,且当每次更新时都会执行::
相当于挂载和更新和销毁前三个生命周期合在了一起。
点击鼠标获取当前位置
import React, {useState, useEffect} from "react";
export const MouseTracker: React.FC = () => {
const [positions, setPositions] = useState({x: 0, y: 0})
useEffect(() => {
console.log('addEffects', positions.x)
// MouseEvent是TS内置对象
const updateMouse = (e: MouseEvent) => {
console.log('inner')
setPositions({x: e.clientX, y: e.clientY})
}
document.addEventListener('click', updateMouse)
return () => {
console.log('removeEffects', positions.x)
document.removeEventListener('click',updateMouse)
}
})
console.log('before render', positions.x)
return (
<div>
<p>X: {positions.x},Y:{positions.y}</p>
</div>
);
};
放在useEffect中,如果绑定事件没有设置解绑,每次都会新绑定,需要对上一次
before render 0
addEffects 0
// 第一次点击也就是更新的时候
inner
before render 257
removeEffects 0
addEffects 257
清除副作用
useEffect(() => {
...
return () => {
... // 清除副作用的代码
}
},[])
return出去的函数中,会在上一次执行副作用和这一次要执行副作用中间对上一次的副作用进行处理。
如何控制useEffect的执行次数
::如果只执行一次:::可以给第二个参数设置为空数组,这个意思就是告诉React,这个Effect不依赖props或state中任意值,所以不会更新,因此只执行一次。
useEffect(() => {
...
},[])
此时再进行点击
before render 0
addEffects 0
//第一次点击
inner
before render 305
//后续点击
inner
before render 325
可以看到useEffect内容只执行了一次,而且return的函数并没有执行
::根据依赖项是否变化来执行::
useEffect(()=>{
...
},[like,on])