Skip to content

Instantly share code, notes, and snippets.

@pwfcurry
Created September 22, 2022 09:39
Show Gist options
  • Save pwfcurry/08001627f50c120a2a6650f42266075f to your computer and use it in GitHub Desktop.
Save pwfcurry/08001627f50c120a2a6650f42266075f to your computer and use it in GitHub Desktop.
'Why did you update' React hook with render count
import { useEffect, useMemo, useRef } from "react";
import { v4 as uuid } from "uuid";
const renderCounter: { [id: string]: number | undefined } = {};
const incrementRenderCount = (id: string) => {
const next = (renderCounter[id] ?? 0) + 1;
renderCounter[id] = next;
return next;
};
// https://usehooks.com/useWhyDidYouUpdate/
export const useWhyDidYouUpdate = (name: string, props: Record<string, unknown>) => {
// Get a mutable ref object where we can store props ...
// ... for comparison next time this hook runs.
const previousProps = useRef<Record<string, unknown>>();
const id = useMemo(() => uuid(), []);
useEffect(() => {
const previous = previousProps.current;
if (previous) {
// Get all keys from previous and current props
const allKeys = Object.keys({ ...previous, ...props });
// Use this object to keep track of changed props
const changesObj: Record<string, unknown> = {};
// Iterate through keys
allKeys.forEach((key) => {
// If previous is different from current
if (previous[key] !== props[key]) {
// Add to changesObj
changesObj[key] = {
from: previous[key],
to: props[key],
};
}
});
// If changesObj not empty then output to console
if (Object.keys(changesObj).length) {
console.log("[why-did-you-update]", name, `[${incrementRenderCount(id)}]`, changesObj);
}
}
// Finally update previousProps with current props for next hook call
previousProps.current = props;
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment