Skip to content

Instantly share code, notes, and snippets.

@timhwang21
Last active February 8, 2019 23:33
Show Gist options
  • Save timhwang21/d16faaa931ad2aae61d7f2e8933d3cc2 to your computer and use it in GitHub Desktop.
Save timhwang21/d16faaa931ad2aae61d7f2e8933d3cc2 to your computer and use it in GitHub Desktop.
Diagnose inefficient renders by identifying "changed" props that are actually equal
import React from "react";
import { isEqual } from "underscore";
/**
* HOC for diagnosing unnecessary renders and identifying faulty selectors
*
* Adds a logger function to a component that lists all changed props
* Also checks if changed props are deeply equal
*
* Usage: Decorate the component you are investigating with renderDoctor:
*
* @renderDoctor
* export default class FlightGridControl extends _Base { ...component code };
*
* @param {node} ComposedComponent Component to decorate
* @return {node} Component decorated with logger
*/
const renderDoctor = ComposedComponent => class extends React.Component {
componentWillReceiveProps(nextProps) {
let propsChange = Object.keys(nextProps).reduce((changedProps, key) => {
if (nextProps[key] !== this.props[key]) {
changedProps = {
...changedProps,
[key]: {
old: this.props[key],
new: nextProps[key],
deepEqual: isEqual(this.props[key], nextProps[key])
}
};
}
return changedProps;
}, {});
if (Object.keys(propsChange).length) {
console.groupCollapsed("%cRender Doctor%c", "color:#AA0000;", "color:#000;");
console.table(propsChange, ['deepEqual']);
console.groupEnd("%cRender Doctor%c", "color:#AA0000;", "color:#000;");
}
}
render() {
return <ComposedComponent {...this.props} />;
}
};
export default renderDoctor;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment