Skip to content

Instantly share code, notes, and snippets.

@andywer
Last active October 23, 2018 17:30
Show Gist options
  • Select an option

  • Save andywer/df91f41b13aaf5d9ff0e0a9ad7e61196 to your computer and use it in GitHub Desktop.

Select an option

Save andywer/df91f41b13aaf5d9ff0e0a9ad7e61196 to your computer and use it in GitHub Desktop.
React Component State Debugger
let lastLoggingTime = Date.now();
function logUpdate (componentName, update, stateBefore, stateAfter, stack) {
const msSinceLastPrint = Date.now() - lastLoggingTime;
console.groupCollapsed(
`%c<${componentName}> setState: %o %c%s`,
"color: #5080ff",
update,
"color: #808080",
msSinceLastPrint < 5000
? `+${msSinceLastPrint}ms`
: `+${(msSinceLastPrint / 1000).toFixed(1)}s`
);
console.log(
" %cState before was: %o",
"color: #ff5050; font-weight: bold",
stateBefore
);
console.log(
" %cState afterwards is: %o",
"color: #37b800; font-weight: bold",
stateAfter
);
console.groupCollapsed("%c Call stack:", "font-weight: normal");
console.log(stack);
console.groupEnd();
console.groupEnd();
lastLoggingTime = Date.now();
};
export function trackStateChanges(Component) {
if (process && process.env && process.env.NODE_ENV === "production") {
return Component;
}
const componentName = Component.displayName || Component.name;
const TrackingComponent = (...args) => {
const component = new Component(...args);
const proto = Object.getPrototypeOf(component);
const originalSetState = proto.setState;
proto.setState = function trackedSetState(update, callback) {
let trackedUpdate = update;
const stack = new Error().stack
.split("\n")
.slice(2)
.join("\n");
if (typeof update === "function") {
trackedUpdate = stateBefore => {
const diff = update(stateBefore);
logUpdate(componentName, diff, stateBefore, { ...stateBefore, ...diff }, stack);
return diff;
};
} else {
trackedUpdate = stateBefore => {
logUpdate(componentName, update, stateBefore, { ...stateBefore, ...update }, stack);
return update;
};
}
return originalSetState.call(this, trackedUpdate, callback);
};
return component;
};
TrackingComponent.displayName = `trackStateChanges(${componentName})`;
return TrackingComponent;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment