Hooks核心04
忘掉 class 组件的声明周期
在函数组件中你要思考的方式永远是:当某个状态发生变化时,我要做什么,而不再是在 class 组件中的某个生命周期方法中我要做什么。
重新思考组件的生命周期
构造函数
在 class 中有个方法叫
constructor
,也就是构造函数,在里面我们会做一些初始化的事情,其实就是在其他代码执行之前的一次性初始工作。
我们可以在函数组件中使用useRef
来实现一个 useSinleton 这样的一次性执行某段代码的自定义 hook,代码如下:
import React, { useRef } from "react"
function useSinleton(callback) {
// 使用called ref来标记callback是否被执行过
const called = useRef(false)
// 如果执行过,则直接返回
if (called.current) return
// 第一次调用直接执行
callback()
// 标记执行过
called.current = true
}
那么我们就可以这样去使用:
import useSinleton from './useSinleton'
function Mydemo = () => {
// 使用自定义hook
useSinleton(()=>{
console.log("这段代码只执行一次!")
})
return <div>My demo</div>
}
三种常用的生命周期方法
- 在类组件中,
componentDidMount
,componentWillUnmout
,componentDidUpdate
最为常用- 在函数组件中,这三者可以统一到 useEffect 这个 hook,正如 useEffect 这个字面函数,其作用就是触发副作用,即在组件每次 render 之后去执行。
useEffect(() => {
// 等价componentDidMount,componentDidUpdate
return () => {
// 等价componentWillUnmout
}
}, [deps])
可以看到,useEffect 接收的 callback 参数,可以返回一个用于清理资源的函数,从而在下一次同样的 useEffect 被执行之前被调用
- useEffect(callback),这个 hook 接收 callback,只有在依赖项发生变化时才被执行。而
componentDidUpdate
则一定会执行。 - callback 返回的函数(一般用于清理工作)在下一次依赖项发生变化时以及组件销毁「之前」执行,而
componentWillUnmout
只有在组件销毁时执行。
思考:useEffect 如果实现只有在组件销毁时或组件挂载完成时才执行?
useEffect(() => {
return () => {}
}, [])
// 关键是依赖项是空数组,表示render完后只执行一次
// 如果有依赖项,则在render后依赖项变化,再去执行return的销毁函数,然后是callback函数