React 实现useWatch

496 阅读1分钟

useWatch

最近在用Vue3的时候发现一个比较好用的hook watch,在回到React项目中虽然有 useEffect 但是使用起来没那么优雅,废话不多说直接使用React实现一个自定义hook useWatch。

源码实现

  • useWatch依赖于 lodash -> isEqual 方法实现更新的值和上一次更新的值是否完全相等做出响应
import { useEffect, useRef } from 'react';
import { isEqual } from 'lodash';


const useWatch = (value, callback, config) => {
  const { immediate = false } = config || {};
  const previousValueRef = useRef();
  const inited = useRef(false);

  useEffect(() => {

    const execute = () => {
      if (!isEqual(previousValueRef.current,value)) {
        callback(value, previousValueRef.current);
      }
    }

    if (!inited.current) {
      inited.current = true
      if (immediate) {
        execute()
      }
    } else {
      execute()
    }

    previousValueRef.current = value;
  }, [value, callback, immediate]);
};

export default useWatch;

使用方式

import React from 'react'

const Demo = () => {
    const [count, setCount] = React.useState(1)
    
    // 页面初始化不执行
    useWatch(count,(newCount)=>{
    
    })
    
    // 需要初始化时执行请将 immediate置为 true
    useWatch(count,(newCount)=>{
    
    }, { immediate: true })
    
    // 需要监听多个状态写成数组格式
    useWatch([data, data1],([newData, newData1], [oldData, oldData1])=>{
    
    }, { immediate: true })

    return (
        <button onClick={()=>setCount(count+1)}></button>
    )
}