学新通技术网

【React】useUpdateEffect(状态更新生命周期)

juejin 13 1
【React】useUpdateEffect(状态更新生命周期)

前言

事情是这样的。今天我要完成的一个功能模块中有一个功能。 这个功能需要我监听状态的改变并做出反应。

然后就有了以下代码👇

image.png

这种写法有一个问题,代码高度耦合。我发现,我所有的周期代码都写在一个函数里面。代码量一多,这个函数会变得很不可读。并且。在完成这个功能的时候。我还需要增加一个本来就可以不存在状态并对他进行逻辑判断。我觉得这样写很不好,可读性和可维护性一般都很一般。

image.png

有那么一瞬间,我有点怀念写Vue的那些时光。怀念Vue的updated生命周期。

我希望React也会有一个类似于update的生命周期。可是他没有。

image.png

为了不被这种胶着的逻辑继续恶心下去,为了不被领导鄙视,也为了和同事装杯。我自己封装了一个useUpdateEffect。

image.png

useUpdateEffect

useUpdateEffect代码实现

useUpdateEffect实现代码👇(附详细注释)

TS版本

/**
 * 自定义hooks 
 * 
 * 用于弥补原先hook的不足
 */

import { DependencyList, EffectCallback, useEffect, useRef } from "react";

//是否时第一次
const isFirstRender = (): boolean => {
    const isFirst: React.MutableRefObject<boolean> = useRef(true); //不会因为重复 render 重复申明, 类似于类组件的 this.xxx
    const { current } = isFirst;
    //如果是第一次,改变状态并返回true
    if (current) {
        isFirst.current = false;
        return true;
    }
    return current;
}

//依赖更改时候生命周期
/**
 * @param effect 更新时所需要调用的函数
 * @param deps  更新的依赖
 */
const useUpdateEffect = (effect: EffectCallback, deps: DependencyList):void => {
    //是否是第一次更新
    const isFirst: boolean = isFirstRender();
    useEffect(() => {
        //如果不是第一次执行函数
        if (!isFirst) return effect();
    }, deps);
}

export {
    useUpdateEffect, //update生命周期
};


useUpdateEffect实现代码👇(附详细注释)

JS版本


import { useEffect, useRef } from "react";

//是否时第一次
const isFirstRender = () => {
    const isFirst = useRef(true); //不会因为重复 render 重复申明, 类似于类组件的 this.xxx
    const { current } = isFirst;
    //如果是第一次,改变状态并返回true
    if (current) {
        isFirst.current = false;
        return true;
    }
    return current;
}

//依赖更改时候生命周期
/**
 * @param effect 更新时所需要调用的函数
 * @param deps  更新的依赖
 */
const useUpdateEffect = (effect, deps) => {
    //是否是第一次更新
    const isFirst = isFirstRender();
    useEffect(() => {
        //如果不是第一次执行函数
        if (!isFirst) return effect();
    }, deps);
}

export {
    useUpdateEffect, //update生命周期
};

上面的代码,直接复制走就可以用。

useUpdateEffect使用方式

image.png

  1. 引入
  2. 使用

使用方式和useEffect没有差别。贼拉方便。

image.png

实现原理

其实实现思想很简单。

简单说就是

设置一个状态true,如果是第一次,则什么都不执行并改变状态为false。

第二次执行判断状态是否为false,如果是,则执行外部传入的函数。

这里有一个需要注意的点是:如何防止我们设置的这个状态true重复声明。useRef是个好东西。这个,可以阻止状态重复声明。

本文出至:学新通技术网

标签: