useWhyDidYouUpdate

This hook makes it easy to see which prop changes are causing a component to re-render. If a function is particularly expensive to run and you know it renders the same results given the same props you can use the React.memo higher order component, as we've done with the Counter component in the below example. In this case if you're still seeing re-renders that seem unnecessary you can drop in the useWhyDidYouUpdate hook and check your console to see which props changed between renders and view their previous/current values.

Usage

useWhyDidYouUpdate.ts
import { useEffect, useRef } from 'react';

type Props = Record<string, any>;

const useWhyDidYouUpdate = (name: string, props: Props) => {
  const previousProps = useRef<Props>(props);

  useEffect(() => {
    if (previousProps.current !== props) {
      const changedProps = Object.entries(props).reduce(
        (acc: Record<string, [any, any]>, [key, value]) => {
          if (previousProps.current[key] !== value) {
            acc[key] = [previousProps.current[key], value];
          }
          return acc;
        },
        {}
      );

      if (Object.keys(changedProps).length) {
        console.log(`[${name}] changed props:`, changedProps);
      }

      previousProps.current = props;
    }
  });
};

export default useWhyDidYouUpdate;

Here's how you can use the useWhyDidYouUpdate hook in a React component:

import { useState } from 'react';
import useWhyDidYouUpdate from './useWhyDidYouUpdate';

const ExampleComponent = ({ propA, propB }: { propA: number, propB: string }) => {
  const [count, setCount] = useState(0);

  useWhyDidYouUpdate('ExampleComponent', { propA, propB, count });

  return (
    <div>
      <p>propA: {propA}</p>
      <p>propB: {propB}</p>
      <p>count: {count}</p>
      <button onClick={() => setCount((prevCount) => prevCount + 1)}>Increment</button>
    </div>
  );
};

export default ExampleComponent;

In this example, the useWhyDidYouUpdate hook takes two arguments: the name of the component and an object containing the props to track. The ExampleComponent uses this hook to log a message whenever its props or state change, indicating which props changed and what their previous and current values were. This can be helpful for debugging and identifying unnecessary re-renders.

Last updated