Last active
October 23, 2018 17:30
-
-
Save andywer/df91f41b13aaf5d9ff0e0a9ad7e61196 to your computer and use it in GitHub Desktop.
React Component State Debugger
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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