@@ -2,6 +2,29 @@ import { useCallback, useRef } from 'react';
22
33export type StableCallback < A extends unknown [ ] , R > = ( ...args : A ) => R ;
44
5+ /**
6+ * A utility hook implementing a stable callback. It takes in an unstable method that
7+ * is supposed to be invoked somewhere deeper in the DOM tree without making it
8+ * change its reference every time the parent component rerenders. It will also return
9+ * the value of the callback if it does return one.
10+ * A common use-case would be having a function whose invocation depends on state
11+ * somewhere high up in the DOM tree and wanting to use the same function deeper
12+ * down, for example in a leaf node and simply using useCallback results in
13+ * cascading dependency hell. If we wrap it in useStableCallback, we would be able
14+ * to:
15+ * - Use the same function as a dependency of another hook (since it is stable)
16+ * - Still invoke it and get the latest state
17+ *
18+ * **Caveats:**
19+ * - Never wrap a function that is supposed to return a React.ReactElement in
20+ * useStableCallback, since React will not know that the DOM needs to be updated
21+ * whenever the callback value changes (for example, renderItem from FlatList must
22+ * never be wrapped in this hook)
23+ * - Always prefer using a standard useCallback/stable function wherever possible
24+ * (the purpose of useStableCallback is to bridge the gap between top level contexts
25+ * and cascading rereders in downstream components - **not** as an escape hatch)
26+ * @param callback - the callback we want to stabilize
27+ */
528export const useStableCallback = < A extends unknown [ ] , R > (
629 callback : StableCallback < A , R > ,
730) : StableCallback < A , R > => {
0 commit comments