Core utilities for building navigators in React Native applications
—
Utilities for converting navigation state to URL paths and vice versa, managing navigation state, finding focused routes, and handling deep linking configurations.
Serialize a navigation state object to a path string for deep linking and URL generation.
/**
* Convert navigation state to a path string
* @param state - Navigation state to serialize
* @param options - Configuration for path generation
* @returns Generated path string
*/
function getPathFromState(
state: NavigationState | PartialState<NavigationState>,
options?: PathConfigOptions
): string;
interface PathConfigOptions {
/** Base path to prepend to generated paths */
path?: string;
/** Initial route name for the root navigator */
initialRouteName?: string;
/** Screen path configuration mapping */
screens?: PathConfigMap<ParamListBase>;
}
type PathConfigMap<ParamList extends ParamListBase> = {
[RouteName in keyof ParamList]?:
| string
| {
path?: string;
exact?: boolean;
parse?: Record<string, (value: string) => any>;
stringify?: Record<string, (value: any) => string>;
screens?: PathConfigMap<any>;
initialRouteName?: string;
};
};Usage Examples:
import { getPathFromState } from "@react-navigation/core";
// Basic path generation
const state = {
index: 1,
routes: [
{ name: 'Home' },
{ name: 'Profile', params: { userId: '123' } }
]
};
const path = getPathFromState(state);
// Result: "/Profile/123"
// With custom path configuration
const config = {
screens: {
Home: '/',
Profile: '/user/:userId',
Settings: {
path: '/settings/:section',
parse: {
section: (value) => value.toLowerCase()
}
}
}
};
const customPath = getPathFromState(state, config);
// Result: "/user/123"
// Complex nested state
const nestedState = {
index: 0,
routes: [
{
name: 'Main',
state: {
index: 1,
routes: [
{ name: 'Home' },
{
name: 'Profile',
params: { userId: '123', tab: 'posts' }
}
]
}
}
]
};
const nestedPath = getPathFromState(nestedState, {
screens: {
Main: {
screens: {
Home: 'home',
Profile: 'profile/:userId/:tab'
}
}
}
});
// Result: "/profile/123/posts"Parse a path string to initial navigation state object for deep linking.
/**
* Convert a path string to navigation state
* @param path - Path string to parse
* @param options - Configuration for path parsing
* @returns Parsed navigation state or undefined if invalid
*/
function getStateFromPath(
path: string,
options?: PathConfigOptions
): PartialState<NavigationState> | undefined;Usage Examples:
import { getStateFromPath } from "@react-navigation/core";
// Basic path parsing
const state = getStateFromPath('/Profile/123');
// Result: {
// routes: [{ name: 'Profile', params: { '0': '123' } }]
// }
// With path configuration
const config = {
screens: {
Home: '/',
Profile: '/user/:userId',
Settings: {
path: '/settings/:section',
parse: {
section: (value) => value.toLowerCase()
}
}
}
};
const parsedState = getStateFromPath('/user/123', config);
// Result: {
// routes: [{ name: 'Profile', params: { userId: '123' } }]
// }
// Complex nested paths
const nestedConfig = {
screens: {
Main: {
screens: {
Home: 'home',
Profile: 'profile/:userId/:tab'
}
}
}
};
const nestedState = getStateFromPath('/profile/123/posts', nestedConfig);
// Result: {
// routes: [{
// name: 'Main',
// state: {
// routes: [{
// name: 'Profile',
// params: { userId: '123', tab: 'posts' }
// }]
// }
// }]
// }
// Query parameters
const stateWithQuery = getStateFromPath('/profile/123?tab=posts&sort=date');
// Result: {
// routes: [{
// name: 'Profile',
// params: { '0': '123', tab: 'posts', sort: 'date' }
// }]
// }Get a navigation action object that would produce the given navigation state.
/**
* Convert navigation state to navigation action
* @param state - Target navigation state
* @param options - Configuration for action generation
* @returns Navigation action that produces the state
*/
function getActionFromState(
state: PartialState<NavigationState>,
options?: PathConfigOptions
): NavigationAction | undefined;Usage Examples:
import { getActionFromState } from "@react-navigation/core";
const state = {
routes: [
{ name: 'Home' },
{ name: 'Profile', params: { userId: '123' } }
]
};
const action = getActionFromState(state);
// Result: NavigationAction that navigates to Profile with userId: '123'
// Use with navigation dispatch
function navigateToStateFromUrl(url) {
const state = getStateFromPath(url, pathConfig);
if (state) {
const action = getActionFromState(state, pathConfig);
if (action) {
navigation.dispatch(action);
}
}
}Find the currently focused route in a navigation state.
/**
* Find the focused route in navigation state
* @param state - Navigation state to search
* @returns The focused route object
*/
function findFocusedRoute(state: NavigationState): Route<string>;Usage Examples:
import { findFocusedRoute } from "@react-navigation/core";
const state = {
index: 1,
routes: [
{ name: 'Home', key: 'home-1' },
{
name: 'Profile',
key: 'profile-1',
state: {
index: 0,
routes: [
{ name: 'Info', key: 'info-1' }
]
}
}
]
};
const focusedRoute = findFocusedRoute(state);
// Result: { name: 'Info', key: 'info-1' }
// Use for getting current screen name
function getCurrentScreenName(navigationState) {
const focused = findFocusedRoute(navigationState);
return focused.name;
}Extract the focused route name from a route object that may contain nested navigation state.
/**
* Get focused route name from a route object
* @param route - Route object potentially containing nested state
* @returns Name of the focused route
*/
function getFocusedRouteNameFromRoute(route: Partial<Route<string>>): string | undefined;Usage Examples:
import { getFocusedRouteNameFromRoute } from "@react-navigation/core";
// Route with nested state
const route = {
name: 'Main',
state: {
index: 1,
routes: [
{ name: 'Home' },
{ name: 'Profile' }
]
}
};
const focusedName = getFocusedRouteNameFromRoute(route);
// Result: 'Profile'
// Use in navigator options
function getHeaderTitle(route) {
const routeName = getFocusedRouteNameFromRoute(route) ?? route.name;
switch (routeName) {
case 'Home':
return 'Welcome';
case 'Profile':
return 'My Profile';
default:
return routeName;
}
}Validate path configuration object for deep linking setup.
/**
* Validate path configuration for correctness
* @param config - Path configuration to validate
* @throws Error if configuration is invalid
*/
function validatePathConfig(config: PathConfigOptions): void;Usage Examples:
import { validatePathConfig } from "@react-navigation/core";
const config = {
screens: {
Home: '/',
Profile: '/user/:userId',
Settings: {
path: '/settings/:section',
parse: {
section: (value) => value.toLowerCase()
}
}
}
};
try {
validatePathConfig(config);
console.log('Configuration is valid');
} catch (error) {
console.error('Invalid configuration:', error.message);
}
// Invalid configuration example
const invalidConfig = {
screens: {
Home: '/',
Profile: '/', // Duplicate path
}
};
validatePathConfig(invalidConfig); // Throws errorHigher-order function to create Navigator, Screen, and Group components for custom navigators.
/**
* Create navigator factory for custom navigators
* @param Navigator - Custom navigator component
* @returns Factory function that creates Navigator/Screen/Group components
*/
function createNavigatorFactory<
State extends NavigationState,
ScreenOptions extends {},
EventMap extends EventMapBase,
Navigator extends React.ComponentType<any>
>(
Navigator: Navigator
): <ParamList extends ParamListBase>() => TypedNavigator<{
ParamList: ParamList;
NavigatorID: string | undefined;
State: State;
ScreenOptions: ScreenOptions;
EventMap: EventMap;
NavigationList: any;
Navigator: Navigator;
}>;
interface TypedNavigator<T> {
Navigator: React.ComponentType<any>;
Screen: React.ComponentType<any>;
Group: React.ComponentType<any>;
}Usage Examples:
import { createNavigatorFactory, useNavigationBuilder } from "@react-navigation/core";
import { StackRouter } from "@react-navigation/routers";
// Custom navigator component
function CustomNavigator({ initialRouteName, children, ...rest }) {
const { state, navigation, descriptors, NavigationContent } = useNavigationBuilder(
StackRouter,
{
children,
initialRouteName,
...rest,
}
);
return (
<NavigationContent>
<View style={{ flex: 1 }}>
{state.routes.map((route, index) => {
const descriptor = descriptors[route.key];
const isFocused = state.index === index;
return (
<View
key={route.key}
style={{
flex: 1,
display: isFocused ? 'flex' : 'none'
}}
>
{descriptor.render()}
</View>
);
})}
</View>
</NavigationContent>
);
}
// Create navigator factory
const createCustomNavigator = createNavigatorFactory(CustomNavigator);
// Use the factory
function createMyNavigator() {
return createCustomNavigator<{
Home: undefined;
Profile: { userId: string };
}>();
}
const MyNavigator = createMyNavigator();
// Usage in app
function App() {
return (
<BaseNavigationContainer>
<MyNavigator.Navigator initialRouteName="Home">
<MyNavigator.Screen name="Home" component={HomeScreen} />
<MyNavigator.Screen name="Profile" component={ProfileScreen} />
</MyNavigator.Navigator>
</BaseNavigationContainer>
);
}Install with Tessl CLI
npx tessl i tessl/npm-react-navigation--core