Multi-Screen Tours
React Native Lumen supports tours that span multiple screens — for example, tabs in a bottom navigation bar.
The Problem
When using a navigator (e.g. BottomTabNavigator, CurvedBottomBar), TourZone components on inactive screens are not mounted. If the tour advances to a step on an unmounted screen, it would fail because that step hasn't been registered or measured yet.
The Solution: Screen-Grouped stepsOrder
Pass stepsOrder as an object where keys are screen names and values are arrays of step keys for that screen:
<TourProvider
stepsOrder={{
ProfileSelf: ['bio', 'prompt', 'poll'],
HomeSwipe: ['filters'],
SwipeableCards: ['swipeableCards'],
}}
config={{
springConfig: SnappySpringConfig,
preventInteraction: true,
}}
>
<BottomTabNavigator />
</TourProvider>
This is logically equivalent to the flat array below, but carries screen-grouping metadata that the library uses to manage cross-screen transitions:
stepsOrder={['bio', 'prompt', 'poll', 'filters', 'swipeableCards']}
What Happens During a Screen Transition
When the tour advances to a step on a different screen:
- The overlay hides automatically.
- The tour enters a pending state, waiting for that step's
TourZoneto mount. - When the user navigates to the correct screen and the
TourZonemounts, the tour resumes automatically.
Flat Array (Also Cross-Screen Compatible)
You can still use a flat array for multi-screen tours. The behavior is identical — if the next step isn't mounted, the tour enters a pending state and resumes when it mounts:
stepsOrder={['bio', 'prompt', 'poll', 'filters', 'swipeableCards']}
Full Example
// App.tsx
<TourProvider
stepsOrder={{
ProfileSelf: ['bio', 'prompt', 'poll'],
HomeSwipe: ['filters'],
SwipeableCards: ['swipeableCards'],
}}
config={{ springConfig: SnappySpringConfig }}
>
<BottomTabNavigator />
</TourProvider>
// ProfileSelf.tsx
<TourZone stepKey="bio" order={1} description="Edit your bio.">
<Bio />
</TourZone>
<TourZone stepKey="prompt" order={2} description="Add prompts.">
<PromptCard />
</TourZone>
<TourZone stepKey="poll" order={3} description="Create polls.">
<PollCard />
</TourZone>
// HomeSwipe.tsx
<TourZone stepKey="filters" order={1} description="Filter your matches.">
<FilterButton />
</TourZone>
// SwipeableCards.tsx
<TourZone stepKey="swipeableCards" order={1} description="Swipe to match!">
<CardStack />
</TourZone>
When the tour finishes the ProfileSelf steps and calls next() on the last step (poll), the overlay hides. Once the user navigates to HomeSwipe, the filters TourZone mounts and the tour automatically resumes.