react-navigation/react-navigation · error · Error
useFrameSize must be used within a FrameSizeProvider
Error message
useFrameSize must be used within a FrameSizeProvider
What it means
useFrameSize reads FrameContext to subscribe to frame (window/screen) size updates with a selector. The context is provided by FrameSizeProvider, which react-navigation sets up internally around navigator content; when absent, the hook has nothing to subscribe to and throws.
Source
Thrown at packages/elements/src/useFrameSize.tsx:35
type FrameContextType = {
getCurrent: () => Frame;
subscribe: (listener: Listener) => RemoveListener;
subscribeThrottled: (listener: Listener) => RemoveListener;
};
const FrameContext = getNamedContext<FrameContextType | undefined>(
'FrameContext',
undefined
);
export function useFrameSize<T>(
selector: (frame: Frame) => T,
throttle?: boolean
): T {
const context = React.use(FrameContext);
if (context == null) {
throw new Error('useFrameSize must be used within a FrameSizeProvider');
}
const value = useSyncExternalStoreWithSelector(
throttle ? context.subscribeThrottled : context.subscribe,
context.getCurrent,
context.getCurrent,
selector
);
return value;
}
type FrameSizeProviderProps = {
initialFrame: Frame;
render: (props: {
ref: React.RefObject<React.ComponentRef<typeof View> | null>;
onLayout: (event: LayoutChangeEvent) => void;
}) => React.ReactNode;View on GitHub (pinned to ab1319d6bb)
Solutions
- Render the consuming component inside a navigator (screen content) so FrameSizeProvider from react-navigation wraps it
- Align @react-navigation/elements with your navigator package versions so the internal FrameSizeProvider is present
- Wrap standalone usage manually in FrameSizeProvider with an explicit frame value
- For tests/stories, wrap the component in a FrameSizeProvider mock provider
Example fix
// before
// App root — outside any navigator
const tabHeight = useFrameSize(f => f.height); // throws
// after
function ScreenContent() { // rendered inside a navigator screen
const tabHeight = useFrameSize(f => f.height);
return <View />;
} Defensive patterns
Strategy: fallback
Validate before calling
import { FrameContext } from '@react-navigation/elements';
const ctx = React.useContext(FrameContext);
if (ctx == null) console.warn('useFrameSize used outside FrameSizeProvider'); Type guard
function useFrameSizeSafe<T>(selector: (f: Frame) => T, fallback: T): T {
const ctx = React.useContext(FrameContext);
return ctx == null ? fallback : selector(ctx.getCurrent());
} Try / catch
Not applicable — context hooks throw on render. Use a provider or guarded context read: const width = React.useContext(FrameContext)?.getCurrent().width ?? fallbackWidth;
Prevention
- Use the hook only inside navigator screen content where FrameSizeProvider is mounted
- Keep @react-navigation/elements in sync with your navigator package versions
- In tests/stories, wrap components in a FrameSizeProvider
When it happens
Trigger: Calling useFrameSize() outside the provider tree — e.g. in the app root above NavigationContainer, in a modal/portal rendered outside the navigator, or in a component used before the internal FrameSizeProvider mounts (older/mismatched package versions where the provider isn't installed).
Common situations: Using useFrameSize-derived helpers (tabBarHeight, header defaults) in custom components placed outside navigator screens; version mismatch between @react-navigation/elements and navigator packages so the provider isn't rendered; tests rendering hooks without navigator wrappers.
Related errors
- Couldn't find a drawer. Is your component inside a drawer na
- Couldn't find the header height. Are you inside a screen in
- Couldn't find values for tab animation. Are you inside a scr
- Couldn't find the bottom tab bar height. Are you inside a sc
- Couldn't find a navigation builder context. Is your componen
AI-assisted analysis of react-navigation/react-navigation@ab1319d6bb (2026-08-31).
Data as JSON: /api/errors/ae711e3d11a76aa0.
Report an issue: GitHub.