Skip to content

Instantly share code, notes, and snippets.

@click2install
Last active August 12, 2021 08:33
Show Gist options
  • Save click2install/ed8600c8f773393e634618604d4861a4 to your computer and use it in GitHub Desktop.
Save click2install/ed8600c8f773393e634618604d4861a4 to your computer and use it in GitHub Desktop.
[useLogStateChanges] - A React hook to log state changes within a functional component or hook.
// using ts-nameof
useLogStateChanges(nameof(SomeComponent),
[
[nameof(value), value],
[nameof(startDate), startDate, val => (val as Date).valueOf().toString()],
[nameof(endDate), endDate]
]);
// using strings :(
useLogStateChanges("SomeComponent",
[
["value", value],
["startDate", startDate, val => (val as Date).valueOf().toString()],
["endDate", endDate]
]);
// output
[SomeComponent] startDate changed from 1609572829743 to 1610264029743.
[SomeComponent] endDate changed from Sat Jan 09 2021 18:33:49 GMT+1100 (Australian Eastern Daylight Time) to Sun Jan 17 2021 18:33:49 GMT+1100 (Australian Eastern Daylight Time).
// First line logs the transform functions output
// Second line logs the interpolated string value of the state variable
import { useRef, useEffect } from "react";
/**
* Simple hook to log state changes.
*
* @export
* @param {string} name The name of the logger
* @param {[string, unknown, ((value: unknown) => string)?][]} [items=[]]
* @param {items.[0]} string The state property name
* @param {items.[1]} unknown The state property value
* @param {items.[2]?} ((value: unknown) => string) An optional transform function for logging the value of the state property
*/
export function useLogStateChanges(name: string, items: [string, unknown, ((value: unknown) => string)?][] = [])
{
const ref = useRef(items);
useEffect(() =>
{
const newValues: Record<string, unknown> = items.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
ref.current
.filter(([key, value]) => value !== newValues[key])
.forEach(([key, value, transform]) =>
{
const oldValue = transform ? transform(value) : value;
const newValue = transform ? transform(newValues[key]) : newValues[key];
// eslint-disable-next-line no-console
console.log(`[${name}] ${key} changed from ${oldValue} to ${newValue}.`);
});
ref.current = items;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment