react-navigation/react-navigation · warning
Looks like you're passing an inline function for 'component'
Error message
Looks like you're passing an inline function for 'component' prop for the screen '${name}' (e.g. component={() => <SomeComponent />}). Passing an inline function will cause the component state to be lost on re-render and cause perf issues since it's re-created every render. You can pass the function as children to 'Screen' instead to achieve the desired behaviour. What it means
getRouteConfigsFromChildren inspects each Screen's component prop. If the function's name is literally 'component' — the tell-tale name of an inline arrow function assigned to the component prop — the library warns that a new component type is created every render, so React will unmount/remount the screen and lose its state. It suggests passing the component as children to Screen instead. This is a console.warn, not a throw.
Source
Thrown at packages/core/src/useNavigationBuilder.tsx:270
if (component !== undefined && !isValidElementType(component)) {
throw new Error(
`Got an invalid value for 'component' prop for the screen '${name}'. It must be a valid React Component.`
);
}
if (getComponent !== undefined && typeof getComponent !== 'function') {
throw new Error(
`Got an invalid value for 'getComponent' prop for the screen '${name}'. It must be a function returning a React Component.`
);
}
if (typeof component === 'function') {
if (component.name === 'component') {
// Inline anonymous functions passed in the `component` prop will have the name of the prop
// It's relatively safe to assume that it's not a component since it should also have PascalCase name
// We won't catch all scenarios here, but this should catch a good chunk of incorrect use.
console.warn(
`Looks like you're passing an inline function for 'component' prop for the screen '${name}' (e.g. component={() => <SomeComponent />}). Passing an inline function will cause the component state to be lost on re-render and cause perf issues since it's re-created every render. You can pass the function as children to 'Screen' instead to achieve the desired behaviour.`
);
} else if (/^[a-z]/.test(component.name)) {
console.warn(
`Got a component with the name '${component.name}' for the screen '${name}'. React Components must start with an uppercase letter. If you're passing a regular function and not a component, pass it as children to 'Screen' instead. Otherwise capitalize your component's name.`
);
}
}
} else {
throw new Error(
`Couldn't find a 'component', 'getComponent' or 'children' prop for the screen '${name}'. This can happen if you passed 'undefined'. You likely forgot to export your component from the file it's defined in, or mixed up default import and named import when importing.`
);
}
});
}
return configs;
};View on GitHub (pinned to ab1319d6bb)
Solutions
- Pass the component as children: <Stack.Screen name="Home">{() => <HomeScreen />}</Stack.Screen> or better <Stack.Screen name="Home"><HomeScreen /></Stack.Screen>.
- Reference a top-level/hoisted component directly: component={HomeScreen} instead of component={() => <HomeScreen />} — keep it defined outside the render.
- If you must pass props, use children with a callback <Screen>{(props) => <HomeScreen {...props} extra={x} />}</Screen>, or hoist props via context so the component identity is stable.
Example fix
// before
<Stack.Screen name="Home" component={() => <HomeScreen />} />
// after
<Stack.Screen name="Home" component={HomeScreen} />
// or with props/state
<Stack.Screen name="Home">{(props) => <HomeScreen {...props} />}</Stack.Screen> Defensive patterns
Strategy: type-guard
Validate before calling
function assertStableComponent(component: unknown): void {
if (typeof component === 'function' && component.name === 'component') {
throw new Error('Pass a hoisted component or children to Screen instead of an inline arrow for `component`.');
}
} Type guard
function isInlineArrow(fn: Function): boolean {
return fn.name === 'component' || fn.name === ''; // inline props are named after the prop
} Prevention
- Always reference hoisted components: component={MyScreen}, never component={() => <MyScreen />}.
- Define screen components at module scope, outside the navigator's render body.
- Use Screen children ({(props) => ...}) when you need to pass extra props.
- Run the app in dev mode and fix any console.warn from useNavigationBuilder immediately.
When it happens
Trigger: Writing <Stack.Screen name="Home" component={() => <HomeScreen />} /> — an inline arrow/anonymous function for the component prop — during navigator configuration.
Common situations: Defining screens inline inside a render function, often to close over props or state; quick prototyping with arrow components; defining a navigator component body without memoizing screen components defined inline as const-less arrow functions.
Related errors
- Got a component with the name '${component.name}' for the sc
- Couldn't find a route at index ${index}.
- The path pattern '${segment}' does not allow null for param
- The path pattern '${segment}' requires a string for param '$
- The path pattern '${segment}' requires at least one value fo
AI-assisted analysis of react-navigation/react-navigation@ab1319d6bb (2026-08-31).
Data as JSON: /api/errors/b085c4d1fd7948b0.
Report an issue: GitHub.