0
# Tab View Component
1
2
The TabView component is the main container that renders the swipeable tab interface with navigation state management. It provides smooth animations, gesture support, lazy loading capabilities, and integrates with the broader React Navigation ecosystem.
3
4
## Capabilities
5
6
### TabView Component
7
8
Core container component that manages navigation state and renders tab scenes with swipe gestures.
9
10
```typescript { .api }
11
/**
12
* Main TabView component for creating swipeable tab interfaces
13
* @param props - TabView configuration and event handlers
14
* @returns JSX element containing the complete tab interface
15
*/
16
function TabView<T extends Route>(props: Props<T>): JSX.Element;
17
18
interface Props<T extends Route> extends Omit<PagerProps, 'layoutDirection'> {
19
/** Required callback when active tab index changes */
20
onIndexChange: (index: number) => void;
21
/** Optional callback when tab is selected (before index change) */
22
onTabSelect?: (props: { index: number }) => void;
23
/** Required navigation state containing current index and routes */
24
navigationState: NavigationState<T>;
25
/** Required function to render scene content for each route */
26
renderScene: (props: SceneRendererProps & { route: T }) => React.ReactNode;
27
/** Optional placeholder renderer for lazy-loaded scenes */
28
renderLazyPlaceholder?: (props: { route: T }) => React.ReactNode;
29
/** Optional custom tab bar renderer (defaults to TabBar component) */
30
renderTabBar?: (props: SceneRendererProps & {
31
navigationState: NavigationState<T>;
32
options: Record<string, TabDescriptor<T>> | undefined;
33
}) => React.ReactNode;
34
/** Tab bar position - 'top' or 'bottom' (default: 'top') */
35
tabBarPosition?: 'top' | 'bottom';
36
/** Initial layout dimensions for proper sizing */
37
initialLayout?: Partial<Layout>;
38
/** Enable lazy loading - boolean or function to determine per route */
39
lazy?: boolean | ((props: { route: T }) => boolean);
40
/** Distance ahead to preload lazy scenes (default: 0) */
41
lazyPreloadDistance?: number;
42
/** Text direction override - 'ltr' or 'rtl' */
43
direction?: LocaleDirection;
44
/** Style for the pager container */
45
pagerStyle?: StyleProp<ViewStyle>;
46
/** Style for the main TabView container */
47
style?: StyleProp<ViewStyle>;
48
/** Per-route options for tab appearance and behavior */
49
options?: Record<string, TabDescriptor<T>>;
50
/** Common options applied to all tabs */
51
commonOptions?: TabDescriptor<T>;
52
}
53
```
54
55
**Usage Examples:**
56
57
```typescript
58
import React, { useState } from 'react';
59
import { View, Text, ActivityIndicator } from 'react-native';
60
import { TabView, SceneMap, NavigationState, Route } from 'react-native-tab-view';
61
62
// Basic TabView with SceneMap
63
const BasicExample = () => {
64
const [index, setIndex] = useState(0);
65
const [routes] = useState([
66
{ key: 'home', title: 'Home' },
67
{ key: 'profile', title: 'Profile' },
68
]);
69
70
const renderScene = SceneMap({
71
home: () => <View><Text>Home Content</Text></View>,
72
profile: () => <View><Text>Profile Content</Text></View>,
73
});
74
75
return (
76
<TabView
77
navigationState={{ index, routes }}
78
renderScene={renderScene}
79
onIndexChange={setIndex}
80
initialLayout={{ width: 375 }}
81
/>
82
);
83
};
84
85
// Advanced TabView with lazy loading and custom rendering
86
const AdvancedExample = () => {
87
const [index, setIndex] = useState(0);
88
const [routes] = useState([
89
{ key: 'feed', title: 'Feed' },
90
{ key: 'search', title: 'Search' },
91
{ key: 'notifications', title: 'Notifications' },
92
]);
93
94
const renderScene = ({ route }: { route: Route }) => {
95
switch (route.key) {
96
case 'feed':
97
return <FeedScreen />;
98
case 'search':
99
return <SearchScreen />;
100
case 'notifications':
101
return <NotificationsScreen />;
102
default:
103
return null;
104
}
105
};
106
107
const renderLazyPlaceholder = ({ route }: { route: Route }) => (
108
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
109
<ActivityIndicator size="large" />
110
<Text>Loading {route.title}...</Text>
111
</View>
112
);
113
114
return (
115
<TabView
116
navigationState={{ index, routes }}
117
renderScene={renderScene}
118
renderLazyPlaceholder={renderLazyPlaceholder}
119
onIndexChange={setIndex}
120
lazy
121
lazyPreloadDistance={1}
122
tabBarPosition="bottom"
123
swipeEnabled={true}
124
animationEnabled={true}
125
initialLayout={{ width: 375, height: 667 }}
126
/>
127
);
128
};
129
```
130
131
### Navigation State Management
132
133
The navigation state is the core data structure that drives the TabView behavior.
134
135
```typescript { .api }
136
/**
137
* Navigation state interface defining current tab and available routes
138
*/
139
interface NavigationState<T extends Route> {
140
/** Zero-based index of the currently active tab */
141
index: number;
142
/** Array of route objects defining available tabs */
143
routes: T[];
144
}
145
146
/**
147
* Base route interface that all tab routes must extend
148
*/
149
interface Route {
150
/** Unique identifier for the route */
151
key: string;
152
/** Optional display title for the tab */
153
title?: string;
154
/** Optional icon identifier */
155
icon?: string;
156
/** Optional accessibility properties */
157
accessible?: boolean;
158
accessibilityLabel?: string;
159
testID?: string;
160
}
161
```
162
163
### Scene Rendering
164
165
Scene rendering provides the content for each tab and receives navigation context.
166
167
```typescript { .api }
168
/**
169
* Props passed to scene render functions
170
*/
171
interface SceneRendererProps {
172
/** Current layout dimensions */
173
layout: Layout;
174
/** Animated position value for transitions */
175
position: Animated.AnimatedInterpolation<number>;
176
/** Function to programmatically navigate to a route */
177
jumpTo: (key: string) => void;
178
}
179
180
/**
181
* Layout dimensions interface
182
*/
183
interface Layout {
184
/** Container width in pixels */
185
width: number;
186
/** Container height in pixels */
187
height: number;
188
}
189
```
190
191
### Tab Configuration
192
193
Configure individual tab appearance and behavior using TabDescriptor.
194
195
```typescript { .api }
196
/**
197
* Configuration object for tab appearance and behavior
198
*/
199
interface TabDescriptor<T extends Route> {
200
/** Accessibility label override */
201
accessibilityLabel?: string;
202
/** Accessibility enabled flag */
203
accessible?: boolean;
204
/** Test identifier */
205
testID?: string;
206
/** Tab label text override */
207
labelText?: string;
208
/** Allow font scaling for label */
209
labelAllowFontScaling?: boolean;
210
/** Web navigation href */
211
href?: string;
212
/** Custom label renderer function */
213
label?: (props: {
214
route: T;
215
labelText?: string;
216
focused: boolean;
217
color: string;
218
allowFontScaling?: boolean;
219
style?: StyleProp<TextStyle>;
220
}) => React.ReactNode;
221
/** Label text styling */
222
labelStyle?: StyleProp<TextStyle>;
223
/** Custom icon renderer function */
224
icon?: (props: {
225
route: T;
226
focused: boolean;
227
color: string;
228
size: number;
229
}) => React.ReactNode;
230
/** Custom badge renderer function */
231
badge?: (props: { route: T }) => React.ReactElement;
232
/** Scene container styling */
233
sceneStyle?: StyleProp<ViewStyle>;
234
}
235
```
236
237
### Event Handling
238
239
Handle navigation events and provide custom behavior.
240
241
```typescript { .api }
242
/**
243
* Event object for tab interactions
244
*/
245
interface Event {
246
/** Whether default behavior has been prevented */
247
defaultPrevented: boolean;
248
/** Function to prevent default navigation behavior */
249
preventDefault(): void;
250
}
251
252
/**
253
* Scene context interface
254
*/
255
interface Scene<T extends Route> {
256
/** The route associated with this scene */
257
route: T;
258
}
259
```
260
261
### Platform-Specific Properties
262
263
TabView extends PagerView properties for platform-specific behavior.
264
265
```typescript { .api }
266
/**
267
* Pager-specific properties inherited by TabView
268
*/
269
interface PagerProps {
270
/** Keyboard dismiss behavior */
271
keyboardDismissMode?: 'none' | 'on-drag' | 'auto';
272
/** Enable/disable swipe gestures */
273
swipeEnabled?: boolean;
274
/** Enable/disable page animations */
275
animationEnabled?: boolean;
276
/** Callback when swipe gesture starts */
277
onSwipeStart?: () => void;
278
/** Callback when swipe gesture ends */
279
onSwipeEnd?: () => void;
280
/** Android scroll behavior */
281
overScrollMode?: 'auto' | 'always' | 'never';
282
}
283
```