One hooks a day-- useWhyDidYouUpdate

May 8, 2023 1361hotness 0likes 0comments

let's start with some nonsense

I remember this hooks very well, because at that time, during an interview, I was asked to implement this custom hooks by hand, , so it was prepared for the first hooks in this series.

to see the effect

when our component becomes complex, do you want to know what caused the component to render, or what the value change is, this hooks will solve your problem.

here comes the hooks source code

type IProps = Record<string, unknown>;
/ * *
* what caused the page render to customize hooks
*
*@paramName of the componentName observation component
*@paramData that props needs to observe (data such as current component state or incoming props that may cause rerender)
, /
const useWhyDidYouUpdate = (componentName: any, props: any) => {
  // create a ref object
  let oldPropsRef = useRef<IProps>({});

  useEffect(() => {
    if (oldPropsRef.current) {
      // iterate through all the key of the old and new props
      let keys = Object.keys({ ...oldPropsRef.current, ...props });
      // change the information object
      let changeMessageObj: IProps = {};
      keys.forEach((key) => {
        // compare whether the new and old props are changed, changed and recorded to changeMessageObj
        if (!Object.is(oldPropsRef.current[key], props[key])) {
          changeMessageObj[key] = {
            from: oldPropsRef?.current[key],
            to: props[key],
          };
        }
      });
      // whether there is change information, existence and printing
      if (Object.keys(changeMessageObj).length) {
        console.log(componentName, changeMessageObj);
      }
      // Update ref
      oldPropsRef.current = props;
    }
  });
};

demo complete source code

import React, { useState, useRef, useEffect } from 'react';
import { Button, Statistic } from 'antd';

type IProps = Record<string, unknown>;
/ * *
* what caused the page render to customize hooks
*
*@paramName of the componentName observation component
*@paramData that props needs to observe (data such as current component state or incoming props that may cause rerender)
, /
const useWhyDidYouUpdate = (componentName: any, props: any) => {
  // create a ref object
  let oldPropsRef = useRef<IProps>({});

  useEffect(() => {
    if (oldPropsRef.current) {
      // iterate through all the key of the old and new props
      let keys = Object.keys({ ...oldPropsRef.current, ...props });
      // change the information object
      let changeMessageObj: IProps = {};
      keys.forEach((key) => {
        // compare whether the new and old props are changed, changed and recorded to changeMessageObj
        if (!Object.is(oldPropsRef.current[key], props[key])) {
          changeMessageObj[key] = {
            from: oldPropsRef?.current[key],
            to: props[key],
          };
        }
      });
      // whether there is change information, existence and printing
      if (Object.keys(changeMessageObj).length) {
        console.log(componentName, changeMessageObj);
      }
      // Update ref
      oldPropsRef.current = props;
    }
  });
};

// demonstrate demo
const Demo: React.FC<{ count: number }> = (props) => {
  useWhyDidYouUpdate('useWhyDidYouUpdateComponent', { ...props });

  return (
    <>
      <Statistic title="number:" value={props.count} />
    </>
  );
};

export default () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <Demo count={count} />
      <div>
        <Button
          type="primary"
          onClick={() => setCount((prevCount) => prevCount - 1)}
        >
          count -
        </Button>
        <Button
          type="primary"
          onClick={() => setCount((prevCount) => prevCount + 1)}
          style={{ marginLeft: 8 }}
        >
          count +
        </Button>
      </div>
    </div>
  );
};

reference

interested friends can look at the source code of react-use and ahooks to learn the elegant code 😍 of their predecessors.

InterServer Web Hosting and VPS

Aaron

Hello, my name is Aaron and I am a freelance front-end developer

Comments