apps/web/src/hooks/useStableCallback.ts
import { useInsertionEffect, useRef, useState } from "react";
/** Call only from handlers and effects; render sees the previous commit's fn. */
export function useStableCallback<Args extends ReadonlyArray<unknown>, Result>(
fn: (...args: Args) => Result,
): (...args: Args) => Result {
const latest = useRef(fn);
// Insertion effects run before every layout effect in the commit, so a
// child's layout effect already calls this render's fn.
// oxlint-disable-next-line t3code/no-unreasoned-state-sync -- updates the ref during commit, before any layout effect can call the stable callback
useInsertionEffect(() => {
latest.current = fn;
});
const [stable] = useState(
() =>
(...args: Args) =>
latest.current(...args),
);
return stable;
}