Skip to content

Instantly share code, notes, and snippets.

@sobstel
Created April 29, 2020 16:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sobstel/515e8ece6e5e26d843c4f02c8bc42bff to your computer and use it in GitHub Desktop.
Save sobstel/515e8ece6e5e26d843c4f02c8bc42bff to your computer and use it in GitHub Desktop.
React Navigation (v4) sequential navigator
// @flow
import React, { Component } from 'react';
import _ from 'lodash';
import createStackNavigator from './createStackNavigator';
type Props = {
navigation: *,
};
const DEFAULT_CONFIG = {
sequentialNavigationOptions: {
order: null,
},
};
export default (routes: *, localConfig: * = {}) => {
const config = _.merge({}, DEFAULT_CONFIG, localConfig);
const { order } = config.sequentialNavigationOptions;
const Navigator = createStackNavigator(routes, config);
return class extends Component<Props> {
static router = Navigator.router;
props: Props;
routeNames: string[] = [];
sharedParams = {};
constructor(props: Props) {
super(props);
this.routeNames = order;
if (typeof this.routeNames === 'function') {
this.routeNames = this.routeNames(props.navigation);
}
if (!this.routeNames) {
this.routeNames = Object.keys(props.navigation.router.childRouters);
}
}
onChange = (params: *) => {
this.sharedParams = { ...this.sharedParams, ...params };
};
onSubmit = () => {
const { navigation } = this.props;
const currentRouteName =
navigation.state.routes[navigation.state.index].routeName;
const currentRouteIndex = this.routeNames.indexOf(currentRouteName);
const nextRouteName = this.routeNames[currentRouteIndex + 1];
if (!nextRouteName) {
navigation.dismiss();
navigation.getParam('onComplete', () => {})();
return;
}
const routeParams = {
...navigation.state.params,
...this.sharedParams,
};
navigation.navigate(nextRouteName, routeParams);
};
render() {
const { navigation } = this.props;
const screenProps = {
...navigation.getScreenProps(),
onChange: this.onChange,
onSubmit: this.onSubmit,
};
return <Navigator navigation={navigation} screenProps={screenProps} />;
}
};
};
import React from 'react';
import { withMappedNavigationProps } from 'react-navigation-props-mapper';
import { createSequentialNavigator } from './createSequentialNavigator';
import { ReviewRating, ReviewText } from './screens/review';
const ReviewStack = createSequentialNavigator(
{
ReviewRating: {
screen: withMappedNavigationProps()(ReviewRating),
},
ReviewText: {
screen: withMappedNavigationProps()(ReviewText),
},
},
{
initialRouteName: 'ReviewRating',
defaultNavigationOptions: {
title: "Submit Your Review",
},
sequentialNavigationOptions: {
order: navigation => {
if (navigation.getParam('onlyRaring')) {
return ['ReviewRating'];
}
return [
'ReviewRating',
'ReviewText',
];
},
},
},
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment