or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdscene-map.mdtab-bar-indicator.mdtab-bar-item.mdtab-bar.mdtab-view.md

scene-map.mddocs/

0

# Scene Mapping

1

2

Scene mapping provides utility functions for efficiently mapping route keys to React components and creating scene renderers. The SceneMap function is the most common way to define tab content in React Native Tab View.

3

4

## Capabilities

5

6

### SceneMap Function

7

8

Helper function that creates scene renderers from a mapping of route keys to React components.

9

10

```typescript { .api }

11

/**

12

* Creates a scene renderer function from a component mapping

13

* @param scenes - Object mapping route keys to React components

14

* @returns Scene renderer function compatible with TabView.renderScene

15

*/

16

function SceneMap<T>(scenes: { [key: string]: React.ComponentType<T> }):

17

(props: SceneRendererProps & { route: Route }) => React.ReactElement;

18

```

19

20

**Usage Examples:**

21

22

```typescript

23

import React from 'react';

24

import { View, Text } from 'react-native';

25

import { TabView, SceneMap } from 'react-native-tab-view';

26

27

// Define individual scene components

28

const HomeScreen = () => (

29

<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>

30

<Text>Home Screen</Text>

31

</View>

32

);

33

34

const ProfileScreen = () => (

35

<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>

36

<Text>Profile Screen</Text>

37

</View>

38

);

39

40

const SettingsScreen = () => (

41

<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>

42

<Text>Settings Screen</Text>

43

</View>

44

);

45

46

// Create scene renderer using SceneMap

47

const renderScene = SceneMap({

48

home: HomeScreen,

49

profile: ProfileScreen,

50

settings: SettingsScreen,

51

});

52

53

// Use with TabView

54

const TabViewExample = () => {

55

const [index, setIndex] = useState(0);

56

const [routes] = useState([

57

{ key: 'home', title: 'Home' },

58

{ key: 'profile', title: 'Profile' },

59

{ key: 'settings', title: 'Settings' },

60

]);

61

62

return (

63

<TabView

64

navigationState={{ index, routes }}

65

renderScene={renderScene}

66

onIndexChange={setIndex}

67

/>

68

);

69

};

70

```

71

72

### Advanced Scene Rendering

73

74

For more complex scenarios, you can create custom scene renderers instead of using SceneMap.

75

76

```typescript { .api }

77

/**

78

* Custom scene renderer function type

79

* @param props - Scene renderer props including route and navigation context

80

* @returns React node to render for the scene

81

*/

82

type SceneRenderer<T extends Route> = (

83

props: SceneRendererProps & { route: T }

84

) => React.ReactNode;

85

86

/**

87

* Scene renderer props interface

88

*/

89

interface SceneRendererProps {

90

/** Current layout dimensions */

91

layout: Layout;

92

/** Animated position value for transitions */

93

position: Animated.AnimatedInterpolation<number>;

94

/** Function to navigate to a specific route */

95

jumpTo: (key: string) => void;

96

}

97

```

98

99

**Custom Scene Renderer Examples:**

100

101

```typescript

102

import React from 'react';

103

import { TabView, NavigationState, Route } from 'react-native-tab-view';

104

105

// Custom scene renderer with conditional logic

106

const renderScene = ({ route, layout, position, jumpTo }: SceneRendererProps & { route: Route }) => {

107

switch (route.key) {

108

case 'home':

109

return <HomeScreen layout={layout} position={position} jumpTo={jumpTo} />;

110

case 'profile':

111

return <ProfileScreen userId={getCurrentUserId()} />;

112

case 'settings':

113

return <SettingsScreen onNavigate={jumpTo} />;

114

case 'notifications':

115

return (

116

<NotificationsScreen

117

badgeCount={getNotificationCount()}

118

onMarkAllRead={() => markAllNotificationsRead()}

119

/>

120

);

121

default:

122

return null;

123

}

124

};

125

126

// Scene renderer with props passing

127

const renderSceneWithProps = (sceneProps: SceneRendererProps & { route: Route }) => {

128

const commonProps = {

129

theme: currentTheme,

130

user: currentUser,

131

navigation: sceneProps.jumpTo,

132

};

133

134

switch (sceneProps.route.key) {

135

case 'feed':

136

return <FeedScreen {...commonProps} refreshing={isRefreshing} />;

137

case 'search':

138

return <SearchScreen {...commonProps} query={searchQuery} />;

139

case 'profile':

140

return <ProfileScreen {...commonProps} userId={sceneProps.route.userId} />;

141

default:

142

return null;

143

}

144

};

145

```

146

147

### Scene Component Architecture

148

149

Understanding how SceneMap creates scene components internally.

150

151

```typescript { .api }

152

/**

153

* Internal scene component props

154

*/

155

interface SceneProps {

156

/** Route object */

157

route: any;

158

/** Function to navigate to route */

159

jumpTo: (key: string) => void;

160

/** Animated position value */

161

position: Animated.AnimatedInterpolation<number>;

162

}

163

164

/**

165

* Internal SceneComponent for rendering individual scenes

166

*/

167

declare const SceneComponent: React.MemoExoticComponent<

168

<T extends { component: React.ComponentType<any> } & SceneProps>(

169

props: T

170

) => React.ReactElement

171

>;

172

```

173

174

### Performance Considerations

175

176

SceneMap uses React.memo for performance optimization and efficient re-rendering.

177

178

**Performance Best Practices:**

179

180

```typescript

181

// ✅ Good: Components defined outside render

182

const HomeScreen = React.memo(() => (

183

<View><Text>Home</Text></View>

184

));

185

186

const ProfileScreen = React.memo(() => (

187

<View><Text>Profile</Text></View>

188

));

189

190

const renderScene = SceneMap({

191

home: HomeScreen,

192

profile: ProfileScreen,

193

});

194

195

// ❌ Avoid: Inline components (will recreate on every render)

196

const renderScene = SceneMap({

197

home: () => <View><Text>Home</Text></View>,

198

profile: () => <View><Text>Profile</Text></View>,

199

});

200

201

// ✅ Better: Memoized inline components if necessary

202

const renderScene = SceneMap({

203

home: React.memo(() => <View><Text>Home</Text></View>),

204

profile: React.memo(() => <View><Text>Profile</Text></View>),

205

});

206

```

207

208

### Dynamic Scene Loading

209

210

Handling dynamic route configurations and lazy-loaded scenes.

211

212

```typescript

213

// Dynamic scene mapping based on user permissions

214

const createSceneMap = (userRoles: string[]) => {

215

const scenes: { [key: string]: React.ComponentType } = {

216

home: HomeScreen,

217

profile: ProfileScreen,

218

};

219

220

if (userRoles.includes('admin')) {

221

scenes.admin = AdminScreen;

222

scenes.analytics = AnalyticsScreen;

223

}

224

225

if (userRoles.includes('moderator')) {

226

scenes.moderation = ModerationScreen;

227

}

228

229

return SceneMap(scenes);

230

};

231

232

// Lazy loading with dynamic imports

233

const LazySceneMap = (scenes: { [key: string]: () => Promise<{ default: React.ComponentType }> }) => {

234

const [loadedScenes, setLoadedScenes] = useState<{ [key: string]: React.ComponentType }>({});

235

236

const renderScene = ({ route }: { route: Route }) => {

237

const SceneComponent = loadedScenes[route.key];

238

239

if (SceneComponent) {

240

return <SceneComponent />;

241

}

242

243

// Load scene dynamically

244

const loader = scenes[route.key];

245

if (loader) {

246

loader().then(module => {

247

setLoadedScenes(prev => ({

248

...prev,

249

[route.key]: module.default,

250

}));

251

});

252

}

253

254

return <LoadingPlaceholder />;

255

};

256

257

return renderScene;

258

};

259

260

// Usage with dynamic imports

261

const lazyRenderScene = LazySceneMap({

262

home: () => import('./screens/HomeScreen'),

263

profile: () => import('./screens/ProfileScreen'),

264

settings: () => import('./screens/SettingsScreen'),

265

});

266

```

267

268

### Integration with Navigation Libraries

269

270

SceneMap works seamlessly with React Navigation and other navigation libraries.

271

272

```typescript

273

// Integration with React Navigation

274

import { useNavigation } from '@react-navigation/native';

275

276

const NavigationAwareScreen = () => {

277

const navigation = useNavigation();

278

279

return (

280

<View>

281

<Button

282

title="Go to Details"

283

onPress={() => navigation.navigate('Details')}

284

/>

285

</View>

286

);

287

};

288

289

const renderScene = SceneMap({

290

tabs: NavigationAwareScreen,

291

});

292

293

// Passing navigation props through scene renderer

294

const renderSceneWithNavigation = ({ route, jumpTo }: SceneRendererProps & { route: Route }) => {

295

const navigationProps = {

296

jumpTo,

297

canGoBack: () => true,

298

goBack: () => jumpTo('home'),

299

};

300

301

switch (route.key) {

302

case 'home':

303

return <HomeScreen navigation={navigationProps} />;

304

case 'profile':

305

return <ProfileScreen navigation={navigationProps} />;

306

default:

307

return null;

308

}

309

};

310

```