Skip to content

Instantly share code, notes, and snippets.

@jwalton
Created June 18, 2020 16:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jwalton/2c47fd739d6a3dde4f417cdef67f63c9 to your computer and use it in GitHub Desktop.
Save jwalton/2c47fd739d6a3dde4f417cdef67f63c9 to your computer and use it in GitHub Desktop.
A react hook to figure out why a component is rendering
/* tslint:disable:no-console */
import ld from 'lodash';
import React from 'react';
/**
* Use this hook to figure out why a React component is re-rendering.
* It will log if any properties in `props` have changed. You should
* also pass any state variables into `props` as well.
*
* @param props - The props passed to a react component.
* @param options.disable - If true, do not profile this component.
* @param options.name - A name to use for logging.
*/
export default function useWhyRerender(
props: any,
options: {
disable?: boolean;
name?: string;
} = {}
) {
const prefix = options.name ? `whyRender ${options.name}: ` : 'whyRender:';
const oldProps = React.useRef(props);
if (options.disable) {
oldProps.current = props;
return;
}
if (props === oldProps.current) {
console.log(`${prefix} Props object is the same`);
return;
}
const keys = Object.keys(props);
const oldKeys = Object.keys(oldProps.current);
if (ld.union(keys, oldKeys).length !== keys.length) {
console.log(`${prefix} Prop keys changed`);
oldProps.current = props;
return;
}
const changes = [];
for (const key of keys) {
if (props[key] !== oldProps.current[key]) {
changes.push(`${key}=${props[key]}`);
}
}
if (changes.length > 0) {
console.log(`${prefix} These props changed: ${changes}`);
oldProps.current = props;
return;
}
console.log(`${prefix} No changes - are you using 'React.memo()'?`);
oldProps.current = props;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment