Skip to content
Source
Sign inSign up

useStableCallback.ts

20 lines782 Bytes

1import { useInsertionEffect, useRef, useState } from "react";
2​
3/** Call only from handlers and effects; render sees the previous commit's fn. */
4export function useStableCallback<Args extends ReadonlyArray<unknown>, Result>(
5 fn: (...args: Args) => Result,
6): (...args: Args) => Result {
7 const latest = useRef(fn);
8 // Insertion effects run before every layout effect in the commit, so a
9 // child's layout effect already calls this render's fn.
10 // oxlint-disable-next-line t3code/no-unreasoned-state-sync -- updates the ref during commit, before any layout effect can call the stable callback
11 useInsertionEffect(() => {
12 latest.current = fn;
13 });
14 const [stable] = useState(
15 () =>
16 (...args: Args) =>
17 latest.current(...args),
18 );
19 return stable;