Bottom tab navigator following iOS design guidelines for React Navigation
—
Navigation capabilities including programmatic navigation, event handling, route management, and TypeScript integration for bottom tab navigation.
The navigation prop provides methods for programmatic navigation and tab management.
interface BottomTabNavigationProp<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = keyof ParamList,
NavigatorID extends string | undefined = undefined
> extends NavigationProp<
ParamList,
RouteName,
NavigatorID,
TabNavigationState<ParamList>,
BottomTabNavigationOptions,
BottomTabNavigationEventMap
>, TabActionHelpers<ParamList> {
/**
* Navigate to a tab by name
*/
navigate<RouteName extends keyof ParamList>(
name: RouteName,
params?: ParamList[RouteName]
): void;
/**
* Jump to a tab without invoking navigation logic
*/
jumpTo<RouteName extends keyof ParamList>(
name: RouteName,
params?: ParamList[RouteName]
): void;
}Usage Examples:
import { BottomTabNavigationProp } from '@react-navigation/bottom-tabs';
type TabParamList = {
Home: undefined;
Profile: { userId: string };
Settings: undefined;
};
type HomeScreenNavigationProp = BottomTabNavigationProp<TabParamList, 'Home'>;
function HomeScreen({ navigation }: { navigation: HomeScreenNavigationProp }) {
const navigateToProfile = () => {
navigation.navigate('Profile', { userId: '123' });
};
const jumpToSettings = () => {
navigation.jumpTo('Settings');
};
return (
<View>
<Button title="Go to Profile" onPress={navigateToProfile} />
<Button title="Jump to Settings" onPress={jumpToSettings} />
</View>
);
}Methods for managing tab-specific navigation actions.
interface TabActionHelpers<ParamList extends ParamListBase> {
/**
* Jump to a tab, focusing it without animation
*/
jumpTo<RouteName extends keyof ParamList>(
name: RouteName,
params?: ParamList[RouteName]
): void;
}Usage Examples:
// Inside a screen component
function QuickActionsComponent({ navigation }) {
const quickJumpToTab = (tabName) => {
navigation.jumpTo(tabName);
};
return (
<View style={styles.quickActions}>
<TouchableOpacity onPress={() => quickJumpToTab('Home')}>
<Text>Home</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => quickJumpToTab('Settings')}>
<Text>Settings</Text>
</TouchableOpacity>
</View>
);
}Handle navigation events for tab interactions and transitions.
interface BottomTabNavigationEventMap {
/**
* Event which fires on tapping on the tab in the tab bar.
*/
tabPress: { data: undefined; canPreventDefault: true };
/**
* Event which fires on long press on the tab in the tab bar.
*/
tabLongPress: { data: undefined };
/**
* Event which fires when a transition animation starts.
*/
transitionStart: { data: undefined };
/**
* Event which fires when a transition animation ends.
*/
transitionEnd: { data: undefined };
}Usage Examples:
import { useFocusEffect } from '@react-navigation/native';
function ProfileScreen({ navigation }) {
// Listen to tab press events
React.useEffect(() => {
const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default behavior
e.preventDefault();
// Custom behavior
Alert.alert('Tab pressed!', 'Do something custom');
});
return unsubscribe;
}, [navigation]);
// Listen to transition events
React.useEffect(() => {
const unsubscribeStart = navigation.addListener('transitionStart', () => {
console.log('Transition started');
});
const unsubscribeEnd = navigation.addListener('transitionEnd', () => {
console.log('Transition ended');
});
return () => {
unsubscribeStart();
unsubscribeEnd();
};
}, [navigation]);
return <View>{/* screen content */}</View>;
}Access route information and parameters from screen components.
interface BottomTabScreenProps<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = keyof ParamList,
NavigatorID extends string | undefined = undefined
> {
navigation: BottomTabNavigationProp<ParamList, RouteName, NavigatorID>;
route: RouteProp<ParamList, RouteName>;
}
interface RouteProp<ParamList extends ParamListBase, RouteName extends keyof ParamList> {
key: string;
name: RouteName;
params: ParamList[RouteName];
path?: string;
}Usage Examples:
import { BottomTabScreenProps } from '@react-navigation/bottom-tabs';
type TabParamList = {
Profile: { userId: string; tab?: string };
};
type ProfileScreenProps = BottomTabScreenProps<TabParamList, 'Profile'>;
function ProfileScreen({ navigation, route }: ProfileScreenProps) {
const { userId, tab } = route.params;
React.useEffect(() => {
// Access route parameters
console.log('User ID:', userId);
console.log('Active tab:', tab);
console.log('Route key:', route.key);
console.log('Route name:', route.name);
}, [route]);
return (
<View>
<Text>Profile for user: {userId}</Text>
{tab && <Text>Active tab: {tab}</Text>}
</View>
);
}Access and monitor the navigation state for advanced use cases.
interface TabNavigationState<ParamList extends ParamListBase> {
/**
* Type of the navigation state
*/
type: 'tab';
/**
* Unique key for the navigation state
*/
key: string;
/**
* Index of the currently active tab
*/
index: number;
/**
* Array of route objects for each tab
*/
routes: Array<{
key: string;
name: keyof ParamList;
params?: ParamList[keyof ParamList];
path?: string;
}>;
/**
* History of navigation actions
*/
history?: NavigationAction[];
}Usage Examples:
import { useNavigationState } from '@react-navigation/native';
function TabIndicator() {
const state = useNavigationState(state => state);
if (state?.type !== 'tab') return null;
return (
<View>
<Text>Active tab: {state.routes[state.index].name}</Text>
<Text>Total tabs: {state.routes.length}</Text>
{state.routes.map((route, index) => (
<Text key={route.key}>
{index === state.index ? '● ' : '○ '}
{route.name}
</Text>
))}
</View>
);
}Set up global navigation listeners for the entire tab navigator.
interface NavigationListeners {
/**
* Listener for tab press events
*/
tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
/**
* Listener for tab long press events
*/
tabLongPress?: (e: EventArg<'tabLongPress', false, undefined>) => void;
/**
* Listener for focus events
*/
focus?: (e: EventArg<'focus', false, undefined>) => void;
/**
* Listener for blur events
*/
blur?: (e: EventArg<'blur', false, undefined>) => void;
}Usage Examples:
<Tab.Navigator
screenListeners={({ navigation, route }) => ({
tabPress: (e) => {
// Global tab press handler
console.log(`Tab pressed: ${route.name}`);
},
tabLongPress: (e) => {
// Global tab long press handler
console.log(`Tab long pressed: ${route.name}`);
},
focus: () => {
// Screen came into focus
console.log(`Screen focused: ${route.name}`);
},
blur: () => {
// Screen lost focus
console.log(`Screen blurred: ${route.name}`);
},
})}
>
{/* screens */}
</Tab.Navigator>Support for deep linking with tab navigation.
interface LinkingConfiguration {
screens: {
[K in keyof ParamList]: string | {
path: string;
parse?: Record<string, (value: string) => any>;
stringify?: Record<string, (value: any) => string>;
};
};
}Usage Examples:
import { NavigationContainer } from '@react-navigation/native';
const linking = {
prefixes: ['myapp://'],
config: {
screens: {
TabNavigator: {
screens: {
Home: 'home',
Profile: {
path: 'profile/:userId',
parse: {
userId: (userId: string) => userId,
},
},
Settings: 'settings',
},
},
},
},
};
function App() {
return (
<NavigationContainer linking={linking}>
<Tab.Navigator>
{/* screens */}
</Tab.Navigator>
</NavigationContainer>
);
}Programmatically dispatch navigation actions.
interface NavigationActions {
/**
* Navigate to a route
*/
navigate(name: string, params?: object): void;
/**
* Go back to previous screen
*/
goBack(): void;
/**
* Reset navigation state
*/
reset(state: Partial<TabNavigationState>): void;
/**
* Set new navigation params
*/
setParams(params: object): void;
}Usage Examples:
import { CommonActions } from '@react-navigation/native';
function CustomNavigationComponent({ navigation }) {
const resetToHome = () => {
navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [{ name: 'Home' }],
})
);
};
const updateParams = () => {
navigation.dispatch(
CommonActions.setParams({
userId: 'newUserId',
refresh: true,
})
);
};
return (
<View>
<Button title="Reset to Home" onPress={resetToHome} />
<Button title="Update Params" onPress={updateParams} />
</View>
);
}Install with Tessl CLI
npx tessl i tessl/npm-react-navigation--bottom-tabs