Flow Navigator provides a simplified API for managing navigation flows in your React Native applications with React Navigation. It abstracts the complexity of flow management, allowing individual screens to navigate through the flow using simple methods like goToNextStep
and goToPreviousStep
, without the need to understand the entire navigation stack, or knowing which page exactly is the next one.
- Simplified Flow Management: Get a comprehensive overview of your flow in a single location. This allows new developers to quickly understand the entire flow without the need to examine each page individually.
- Separation of responsibility: Screens are not aware of their specific position in the flow. They don't need to know which page is next; they simply navigate to the next page in the flow.
- Declarative Screen Ordering: Define the order of screens in your navigation flow declaratively, ensuring a clear and maintainable navigation structure.
The flow navigator is built on top of react-navigation's native stack navigator. So it requires both react-navigation and the native stack navigator installed.
To install the flow navigator, run:
yarn add @bam.tech/flow-navigator
# or
npm install @bam.tech/flow-navigator
import { createFlowNavigator } from '@bam.tech/flow-navigator';
const FlowNavigator = createFlowNavigator();
export const FlowNavigatorExample = () => {
// Define your screens and their order in the flow
return (
<FlowNavigator.Navigator>
<FlowNavigator.Screen name="Step1" component={Step1Page} />
<FlowNavigator.Screen name="Step2" component={Step2Page} />
<FlowNavigator.Screen name="Step3" component={Step2Page} />
</FlowNavigator.Navigator>
);
};
In each screen component, you can navigate through the flow using:
import { useFlow } from '@bam.tech/flow-navigator';
const Step1Page = () => {
const { goToNextStep, goToPreviousStep, currentStep } = useFlow();
return (
<Button title="Go to next page" onPress={() => goToNextStep()} />
)
};
You can find a fully working example in the example folder.
In certain scenarios, a flow may include steps that are conditional. These steps might be dependent on user-specific conditions or based on whether certain actions have already been completed. You can manage such conditional steps declaratively in your navigation flow.
Here's an example where "Step 2" is conditionally displayed based on the hasToPassStep2 variable. This variable could be a piece of data fetched from the backend or a state within your application. In our case, we use jotai to store our user data locally.
import { createFlowNavigator } from '@bam.tech/flow-navigator';
export const flagAtom = atom(false);
const FlowNavigator = createFlowNavigator();
export const FlowNavigatorExample = () => {
const [flag] = useAtom(flagAtom);
return (
<FlowNavigator.Navigator>
<FlowNavigator.Screen name="Step1" component={Step1Page} />
{flag && <FlowNavigator.Screen name="Step2" component={Step2Page} />}
<FlowNavigator.Screen name="Step3" component={Step3Page} />
</FlowNavigator.Navigator>
);
};
In this example, the Step2 screen is only included in the flow if hasToPassStep2 evaluates to true.
You can enable or disable routes at anytime in your flow by setting your boolean state: setFlag(false)
import { useFlow } from '@bam.tech/flow-navigator';
export const Step1Page = () => {
const {goBack, goToNextStep} = useFlow();
const [flag] = useAtom(flagAtom);
const onNextPress = async () => {
setFlag(false);
goToNextStep();
};
const onBackPress = () => {
goBack();
};
return (
<View style={styles.container}>
<Text style={styles.pageTitle}>Current page: 1</Text>
<FlowInfos />
<Button title="next" onPress={onNextPress} />
<Button title="back" onPress={onBackPress} />
</View>
);
};
You can check out a fully working example in the example folder
In some scenarios, a single step in a flow may encompass several screens. To group these screens within one step, you have a couple of options: using Groups or Nested navigators. Examples of both approaches can be found in the exa