ReactHook - useEffect

useEffect

作用:
  1. 推迟代码执行
    渲染完成之后再执行,常用于 数据读取

  2. 完成移除 - 组件卸载的时候做一些清理的工作
    例如:定时器、监听等
    有关组件卸载:
    触发时机:当组件从 DOM 中移除时,会触发useEffect里返回的函数,useEffect里的内容不会执行,执行也没有意义了。当组件出现在DOM中时,会执行useEffect里的代码,useEffect里返回的函数不执行。

  3. 第二个参数来模拟生命周期。
    对于缓存的对象来说,因为每次函数都重新执行,因此对象的引用会变,所以useEffect第二个参数缓存的是引用的地址。


useEffect存在一种bail out(保释) / (补救)机制:

当你尝试设置相同的状态,仅仅让你把函数执行完,但不会再触发effect。

同理,在class组件中的setState也是一样。

setState

state设置重复的值 —— 只会重复渲染一次 +1


1. 推迟代码执行

例如:
ReactHook - useEffect_第1张图片

ReactHook - useEffect_第2张图片

上面其实本来就是一种错误的写法,只是React官方帮你兜了个底。

正确的做法是:
ReactHook - useEffect_第3张图片

2. 完成移除 定时器、监听

function HOC() {
    const [count, setCount] = useState(0);
    useEffect(() => {
        console.log('创建')
        return () => {
            console.log('销毁')
        }
    });
    return(
        <>
            <button onClick={() => setCount(count + 1)}>按钮</button>
        </>
    )
}
export default HOC;

当状态变化的时候,重新渲染,重新渲染导致useEffect执行。在第一次刷新的时候,不执行useEffect返回的函数,只执行useEffect里的内容。后面状态变化导致重新渲染的时候,会优先执行useEffect返回的函数,然后再执行useEffect里的内容。

例如:

页面初始化时:
ReactHook - useEffect_第4张图片

第一次点击按钮时:
ReactHook - useEffect_第5张图片


useEffect - clean-up阶段有两个:

  1. 删除组件
  2. 重新渲染当前组件
1. 第一个,删除组件的时候执行:

ReactHook - useEffect_第6张图片

  • 注意:
    1. useEffect里的回调如果有返回值的话,必须是一个函数。
    2. 会先执行这个return函数,例如下面的代码。
2. 第二个,重新渲染的时候执行:

ReactHook - useEffect_第7张图片

上面两种情景这样做的官方总结:

react官方:
1.必要性:极大的提升程序的可靠性
2.函数组件:简单、小型组件

程序可靠性
程序性能

结论:重新渲染的时候就先移除然后重新添加,目的是为了增强稳定性,如果有很庞大的初始化、移除操作,还应该用class(didMount、willUnmount)

注意:

错误的使用state,会导致资源泄露


例如:
1.某种异步操作开始——非常长
2.组件已经被卸载了
3.setState - 资源(内存泄露、socket泄露,主要是内存泄露)泄露

代码如下:
ReactHook - useEffect_第8张图片

会报如下警告⚠️:

Warning: Can’t perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in Unknown (at App.js:13)

解决方法:
ReactHook - useEffect_第9张图片


3. 第三种, 第二个参数来模拟生命周期。

useEffect选择执行:
ReactHook - useEffect_第10张图片
当a变化,才打印effect a;
当b变化,才打印effect b;

类似于 [a] 这种形式 官方叫做 ”跳过“

useEffect模拟生存周期函数:

useEffect(fn, [值]);

如:componentDidMount
在这里插入图片描述

你可能感兴趣的:(React,react.js,javascript,前端)