视频网站备案怎么做,郑州今天出啥大事儿了,lovefort表白网站制作,西安市seo排名按天优化useEffect 基本使用
useEffect 根据传参个数和传参格式#xff0c;它的执行次数和执行结果是不同的。
useEffect(setup, dependencies?)
在没有依赖项数组时#xff0c;每次渲染之后都会执行 Effect依赖项数组可以设置多个依赖项#xff0c;其中任意一项发生变化#x…useEffect 基本使用
useEffect 根据传参个数和传参格式它的执行次数和执行结果是不同的。
useEffect(setup, dependencies?)
在没有依赖项数组时每次渲染之后都会执行 Effect依赖项数组可以设置多个依赖项其中任意一项发生变化Effect 都会执行
需要注意的是
当依赖项是引用类型时React 会比较依赖项的内存地址是否一样如果一致Effect 不会执行。示例如下
import React, { useState, useEffect } from react;const Child ({ data }) {useEffect(() {console.log(useEffect);}, [data]);return div{data.x}/div;
};let data { x: 0 };
const App () {const [count, setCount] useState(0);console.log(render);return (divbuttononClick{() {data.x data.x 1;setCount(count 1);}}click/buttonChild data{data} //div);
};export default App;点击 click 之后对象 data 中的属性值会发生变化但是传入组件 Child / 组件的内存地址没有变化所以 console.log(“useEffect”) 不会执行。为解决这个问题应该使用对象中的属性作为依赖而不是整个对象。应该将上面示例中组件 Child / 修改如下
const Child ({ data }) {useEffect(() {console.log(useEffect);}, [data.x]);return div{data.x}/div;
};useEffect 的执行时机和 useLayoutEffect
useEffect在渲染完成后异步执行不会阻塞浏览器的绘制操作。
然而并非所有的操作都适合放在 useEffect 中延迟执行。例如在浏览器下一次绘制之前需要操作 DOM 改变页面样式或者依赖布局信息渲染组件。如果放在 useEffect 中执行会出现闪屏问题。而 useLayoutEffect 在浏览器执行绘制之前被同步执行使用 useLayoutEffect 可以避免这个问题。
准确绑定依赖
const Example () {const [count, setCount] useState(0);useEffect(() {console.log(useEffect);const timer setInterval(() {console.log(setInterval);setCount(count 1);}, 1000)return () clearInterval(timer);}, [])return p {count} /p;
}在上面例子中useEffect 用到的依赖项 count却没有声明在依赖项中useEffect 不会重复执行只在组件挂载时打印了一次 useEffectsetInterval 中拿到的 count 始终为 0它后面每一秒都会调用 setCount(0 1)得到的结果始终为 1。下面是两种可以正确解决依赖的方法
1. 在依赖项数组中包含所有在 Effect 中用到的值
将 Effect 中用到的外部变量 count 添加到依赖项数组中
useEffect(() {console.log(useEffect);const timer setInterval(() {setCount(count 1);}, 1000)return () {console.log(return${count});clearInterval(timer);}
}, [count])可以看出依赖项数组是正确的并且解决了上面的问题。但是也可以发现随之带来的问题是定时器会在每一次 count 改变后销毁和重新创建这并不是我们想要的结果。
2. 第二种方法是修改 Effect 中的代码来减少依赖项
useEffect(() {console.log(useEffect);const timer setInterval(() {setCount((count) count 1);}, 1000)return () {console.log(return);clearInterval(timer);}
}, [])修改 Effect 内部的代码使 useEffect 的依赖更少这需要一些移除依赖常用的技巧。如setCount 还有一种函数回调模式这种模式不需要关心当前值是什么只需要对 “旧的值” 进行修改即可。这样就不需要把 count 写进依赖项数组这种方式来告诉 React。
是否需要清除副作用
如果只是在 React 更新 DOM 之后运行一些额外的代码如发送网络请求等则无需清除操作。
需要清除的是那些执行之后还有后续的操作如定时器或者页面的监听事件等。为防止内存泄漏可以通过 useEffect 的 return 销毁通过 useEffect 注册的监听。
const Example () {const [count, setCount] useState(0);useEffect(() {console.log(useEffect);return () {console.log(return);}}, [count])return (divp {count} /p{console.log(dom)}button onClick{() setCount(count 1)}click/button/div)
} 从 dom、return、useEffect 的打印结果可以看出useEffect 的清除函数在每次重新渲染时都会执行而不是只在组件卸载时执行。清除函数是在新的渲染之后执行的。