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 被执行之前被调用

  1. useEffect(callback),这个 hook 接收 callback,只有在依赖项发生变化时才被执行。而 componentDidUpdate 则一定会执行。
  2. callback 返回的函数(一般用于清理工作)在下一次依赖项发生变化时以及组件销毁「之前」执行,而 componentWillUnmout 只有在组件销毁时执行。

思考:useEffect 如果实现只有在组件销毁时或组件挂载完成时才执行?

useEffect(() => {
  return () => {}
}, [])
// 关键是依赖项是空数组,表示render完后只执行一次
// 如果有依赖项,则在render后依赖项变化,再去执行return的销毁函数,然后是callback函数

Published under  on .

pipihua

我是皮皮花,一个前后端通吃的前端攻城狮,如果感觉不错欢迎点击小心心♥(ˆ◡ˆԅ) star on GitHub!