实现原理
let _deps; // _deps 记录 useEffect 上一次的 依赖
function useEffect(callback, depArray) {
const hasNoDeps = !depArray; // 如果 dependencies 不存在
const hasChangedDeps = _deps
? !depArray.every((el, i) => el === _deps[i]) // 两次的 dependencies 是否完全相等
: true;
/* 如果 dependencies 不存在,或者 dependencies 有变化*/
if (hasNoDeps || hasChangedDeps) {
callback();
_deps = depArray;
}
}
**应用规则
一、参数规则
1、可选的
2、数组类型
3、值为state或者props
二、不同的参数和返回
1、不传参数
默认的行为,会每次 render 后都执行,一般表单控制中使用
类似于类组件中的componentDidMoount以及componentDidUpdate
useEffect(() => {
console.log('useEffect with no dependency')
})
2、空数组(因为传空数组,所以判断依赖变化时,所有的依赖都没变化,所以只执行一次)
传入第二个参数,每次 render 后比较数组的值没变化,不会在执行
类似于类组件中的 componentDidMount
useEffect(() => {
console.log('useEffect with empty dependency')
}, [])
3、有一个或者多个值得数组
传入第二个参数,只有一个值,比较该值有变化就执行,
传入第二个参数,有2个值的数组,会比较每一个值,有一个不相等就执行
类似于类组件中的componentDidUpdate
useEffect(() => {
console.log('useEffect widh specify dependency')
}, [state, props])
4、返回一个函数
**** 返回时传递一个函数进行卸载,在组件卸载时候调用
类似于类组价中componentWillUnmout
useEffect(() => {
console.log('useEffect widh specify callback');
return () => {
console.log('useEffect with specify callback');
}
})