Skip to content

Instantly share code, notes, and snippets.

@acorn1010
Last active June 13, 2023 11:59
Show Gist options
  • Save acorn1010/17109822ea02242f63b888476aa083d9 to your computer and use it in GitHub Desktop.
Save acorn1010/17109822ea02242f63b888476aa083d9 to your computer and use it in GitHub Desktop.
useEffectDebugger.ts
import {useEffect, useRef} from "react";
/**
* Prefer this to react-use. We're deprecating react-use later.
* Returns `value` from the previous render.
*/
export function usePrevious<T>(value: T, initialValue?: T) {
const ref = useRef<T | undefined>(initialValue);
useEffect(() => {
ref.current = value;
});
return ref;
}
/**
* Replaces a useEffect with a version that outputs why it was triggered.
*
* Example usage:<br />
* ```typescript
* useEffectDebugger(() => {
* // useEffect code here...
* }, {dep1, dep2});
* ```
*/
export default function useEffectDebugger<T extends {readonly [key: string]: unknown}>(
effectHook: () => (void | (() => (void | undefined))),
dependencyNamesToDeps: T) {
const previousDeps = usePrevious(dependencyNamesToDeps, {} as any).current;
const changedDeps: Partial<{[K in keyof T]: {before: T[K], after: T[K]}}> = {};
for (const [name, after] of Object.entries(dependencyNamesToDeps) as [keyof T, T[keyof T]][]) {
const before = previousDeps[name];
if (after !== before) {
changedDeps[name] = {before, after};
}
}
if (Object.keys(changedDeps).length) {
console.log('[use-effect-debugger] ', changedDeps);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(effectHook, Object.values(dependencyNamesToDeps));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment