useEffect
的设计是用来执行一段和当前渲染无关的副作用代码
组件(实例)的生命周期
-
Mount/Initial render
:第一次渲染组件实例,创建新的state
和props
-
re-render
(可选):state
改变时触发props
改变时触发- 父组件重新渲染时触发
Context
改变时触发
-
UnMount
:组件实例被销毁并移除,state
和props
被销毁

在哪里执行副作用?
回顾:副作用是任何"React组件和组件外部世界之间的交互"。我们也可以把副作用看作是"实际做一些事情的代码"。
比如:数据请求、设置订阅、设置计时器、手动访问DOM等。
在React
中,渲染逻辑中(Render Logic)不允许副作用的出现,我们有两种方式去执行副作用:
- Event Handlers(即事件的回调函数):通过事件触发,如
onClick
、onSubmit
useEffect
:允许我们编写将在不同时刻运行的副作用代码:挂载、重新渲染或卸载
Event Handlers VS. useEffect

二者执行后会产生相同的效果,区别就是执行的时机不同
Event Handlers
会在对应的事件触发时执行
useEffect
会在组件挂载后(初始渲染)和随后的重新渲染后执行(由依赖数组决定),同时在组件卸载时会执行return
返回的函数(Cleanup function
)
useEffect
的依赖数组
默认情况下(不传入依赖数组),useEffect
在每次渲染后执行。我们可以通过传入依赖数组来防止这种情况。
没有依赖数组,React不知道什么时候运行useEffect
每当依赖数组中的一个依赖项发生变化时,将再次执行useEffect
useEffect
中使用的每个state
和prop
都必须包含在依赖数组中

useEffect
是一种同步机制
useEffect
就像一个事件监听器,监听一个依赖项的变化。每当依赖项发生变化时,它将再次执行该effect

同步与生命周期

我们可以在组件渲染或重新渲染时使用依赖数组来运行Effect
Effect
和组件生命周期的对应关系

Cleanup Function
Cleanup Function
是useEffect
返回的函数,这个函数会useEffect
再次执行时和组件卸载时执行

每个Effect
应该只做一件事!为每个副作用使用一个useEffect
钩子。这使得Effect
更容易清理
理解
useEffect
和生命周期无关,他是函数组件形态下的另一种设计模式,只能说他能解决我们过去认知中的使用生命周期的一些问题。所以我们首先要转变的思想就是忘掉生命周期,将思考放在如何通过函数组件的重复执行解决上。------奇舞精选