Skip to content

Instantly share code, notes, and snippets.

@notgiorgi
Last active March 6, 2023 14:13
Show Gist options
  • Save notgiorgi/1ee3644cc94fb6e8abfbb58bd1927e7a to your computer and use it in GitHub Desktop.
Save notgiorgi/1ee3644cc94fb6e8abfbb58bd1927e7a to your computer and use it in GitHub Desktop.
import React from 'react'
export function useEffectDebugger(effect, dependencies) {
useLogChanges(dependencies)
React.useEffect(effect, dependencies)
}
export function useCallbackDebugger(callback, dependencies) {
useLogChanges(dependencies)
return React.useCallback(callback, dependencies)
}
export function useMemoDebugger(memoizer, dependencies) {
useLogChanges(dependencies)
return React.useMemo(memoizer, dependencies)
}
function usePrevious(value) {
const ref = React.useRef()
React.useEffect(() => {
ref.current = value
}, [value])
return ref.current
}
function useLogChanges(value) {
const previousValue = usePrevious(value)
const changes = getChanges(previousValue, value)
if (changes.length) {
changes.forEach((change) => {
console.log(change)
})
}
}
function getChanges(previousValue, currentValue) {
// Handle non-null objects
if (
typeof previousValue === 'object' &&
previousValue !== null &&
typeof currentValue === 'object' &&
currentValue !== null
) {
return Object.entries(currentValue).reduce((acc, cur) => {
const [key, value] = cur
const oldValue = previousValue[key]
if (value !== oldValue) {
acc.push({
name: key,
previousValue: oldValue,
currentValue: value
})
}
return acc
}, [])
}
// Handle primitive values
if (previousValue !== currentValue) {
return [{ previousValue, currentValue }]
}
return []
}
import React from 'react'
export function useEffectDebugger(
effect: React.EffectCallback,
dependencies?: React.DependencyList
) {
useLogChanges(dependencies)
React.useEffect(effect, dependencies)
}
export function useCallbackDebugger(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
callback: (...args: any[]) => any,
dependencies: React.DependencyList
) {
useLogChanges(dependencies)
return React.useCallback(callback, dependencies)
}
export function useMemoDebugger(
memoizer: () => unknown,
dependencies?: React.DependencyList
) {
useLogChanges(dependencies)
return React.useMemo(memoizer, dependencies)
}
function usePrevious(value: unknown) {
const ref = React.useRef<unknown>()
React.useEffect(() => {
ref.current = value
}, [value])
return ref.current
}
function useLogChanges(value: unknown) {
const previousValue = usePrevious(value)
const changes = getChanges(previousValue, value)
if (changes.length) {
changes.forEach((change) => {
console.log(change)
})
}
}
function getChanges(previousValue: unknown, currentValue: unknown) {
// Handle non-null objects
if (
typeof previousValue === 'object' &&
previousValue !== null &&
typeof currentValue === 'object' &&
currentValue !== null
) {
return Object.entries(currentValue).reduce<
{
name: string
previousValue: unknown
currentValue: unknown
}[]
>((acc, cur) => {
const [key, value] = cur as [string, unknown]
const oldValue = (previousValue as Record<string, unknown>)[key]
if (value !== oldValue) {
acc.push({
name: key,
previousValue: oldValue,
currentValue: value
})
}
return acc
}, [])
}
// Handle primitive values
if (previousValue !== currentValue) {
return [{ previousValue, currentValue }]
}
return []
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment