React 自定义Hook之usePrevious
概要
本文提供一个获取useState状态变化之前旧值的Hook方法usePrevious,以及该方法的基本实现思路, 实现包括TS版和普通JS版。
基本思路
usePrevious的核心原理,在于React Hooks的执行顺序和引用对象(ref)的持久化特性。
基本原理
初始阶段(页面加载):
- 组件挂载,useRef初始化一个ref对象,此时ref.curret 的值是undifined或传入的初始值;
- 组件渲染,usePrevious 返回undifined或传入的初始值;
- 组件渲染完成,执行监听函数useEffect,将ref.current跟新。
触发状态更新阶段:
调用setXX触发状态更新:
- 组件开始重新渲染;
- usePrevious再次执行,此时:useRef中的数据并未改变,因此返回旧值;所以在组件重新渲染阶段,可以取到旧值;
- 组件用新值完成渲染;
- 组件渲染完成后执行useEffect,更新ref.curret 。
代码实现
TS 版
import { useEffect, useRef } from "react";
export const usePrevious = <T>(value:T): T | undefined => {const ref = useRef<T>(value);useEffect(()=>{ref.current = value;}, [value]);return ref.current;
}
JS版
import { useEffect, useRef } from "react";
export function usePrevious(value){const pValue = useRef(value);useEffect(()=>{pValue.current = value;}, [value]);return pValue.current;
}
结论
获取状态变化前的旧值,可以方便我们在普通的方法中,更好的监听响应式数据的变化,以便我们进行数据验证等操作。