Loading…
Mastering React’s Stable Values
2023-10-18
- Source
- Shopify
- Published
- Added to Yomu
Summary
React stable values are values, often returned by hooks, that retain the same value across renders, and the post explains why their identity matters in effects, callbacks, memoization, and component rendering. useState and useReducer update functions and useRef objects are stable, while array literals, object literals, and anonymous functions are recreated on each render; useCallback and useMemo can produce stable values under appropriate dependencies. Unstable dependencies prevent useEffect behavior from remaining limited to intended changes and stop useCallback and useMemo cached results from being reused, while an unstable callback passed to useFocusEffect causes repeated unsubscribe and resubscribe cycles. The post also contrasts invoking an inline helper with rendering it as a component, explains why the latter can rebuild a React Native subtree on every render, and recommends defining components outside other components and using React.memo or callbacks judiciously.
Context
The post addresses confusion about React stability: which values remain identical across renders, which values are recreated, and why that distinction affects hook dependencies, React Navigation's useFocusEffect, inline component functions, and memoized components.
Approach / What changed
It explains stability through examples involving useState, useReducer, useRef, useCallback, and useMemo, then applies the concept to dependency lists, focus effects, inline functions that return components, and React.memo. It recommends invoking helper functions directly, defining components outside parent component bodies, and applying callback or component memoization selectively.
Takeaways
- useState and useReducer return stable state-update functions, while useRef returns a stable object whose current property can change without triggering a re-render.
- An anonymous callback passed to useFocusEffect is recreated on every render, so the effect may unsubscribe and resubscribe on every render unless the callback is wrapped in useCallback.
- Rendering a function created inside another component as JSX makes React treat it as a new component across renders, causing its child tree to be destroyed and remounted; invoking the helper directly avoids that pitfall.