解读 ahooks 源码系列 - Dev 篇

发布于 2025-01-20 16:45:23 字数 2958 浏览 2 评论 0

本篇文章是解读 ahooks@3.8.0 源码系列的第八篇 - Dev 篇,欢迎您的指正和点赞。

本文主要解读 useTrackedEffect、 useWhyDidYouUpdate 的源码实现。

useTrackedEffect

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

type Effect<T extends DependencyList> = (
  changes?: number[],
  previousDeps?: T,
  currentDeps?: T
) => void | (() => void);

const diffTwoDeps = (deps1?: DependencyList, deps2?: DependencyList) => {
  // Let's do a reference equality check on 2 dependency list.
  // If deps1 is defined, we iterate over deps1 and do comparison on each element with equivalent element from deps2
  // As this func is used only in this hook, we assume 2 deps always have same length.
  return deps1
    ? deps1
        .map((_ele, idx) => (!Object.is(deps1[idx], deps2?.[idx]) ? idx : -1))
        .filter((ele) => ele >= 0)
    : deps2
    ? deps2.map((_ele, idx) => idx)
    : [];
};
const useTrackedEffect = <T extends DependencyList>(
  effect: Effect<T>,
  deps?: [...T]
) => {
  // 上一次的依赖
  const previousDepsRef = useRef<T>();

  useEffect(() => {
    // 变化的依赖 index 数组
    const changes = diffTwoDeps(previousDepsRef.current, deps);
    const previousDeps = previousDepsRef.current;
    previousDepsRef.current = deps;
    return effect(changes, previousDeps, deps);
  }, deps);
};

export default useTrackedEffect;

useWhyDidYouUpdate

import { useEffect, useRef } from "react";

export type IProps = Record<string, any>;

const useWhyDidYouUpdate = (componentName: string, props: IProps) => {
  // 上一次的 props
  const prevProps = useRef<IProps>({});

  useEffect(() => {
    if (prevProps.current) {
      // 获取所有 key
      const allKeys = Object.keys({ ...prevProps.current, ...props });
      const changedProps: IProps = {};
      allKeys.forEach((key) => {
        // 哪些 key 进行了更新
        if (!Object.is(prevProps.current[key], props[key])) {
          changedProps[key] = {
            from: prevProps.current[key],
            to: props[key],
          };
        }
      });
      // 有 diff,控制台输出
      if (Object.keys(changedProps).length) {
        console.log("[why-did-you-update]", componentName, changedProps);
      }
    }
    // 更新 prevProps
    prevProps.current = props;
  });
};

export default useWhyDidYouUpdate;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

苍风燃霜

暂无简介

文章
评论
27 人气
更多

推荐作者

迎风吟唱

文章 0 评论 0

qq_hXErI

文章 0 评论 0

茶底世界

文章 0 评论 0

捎一片雪花

文章 0 评论 0

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文