react-navigation-config
v0.2.2
Published
route configuration helpers for react-navigation
Maintainers
Readme
React Navigation Config
configuration helpers for react-navigation 4.x.
Dependent
- react
- redux
- react-navigation
- react-navigation-drawer
- react-navigation-stack
- react-navigation-tabs
Usage
navigation instance, project created by react-native-cli.
Basic Example
- App.js
import React from "react";
import { View, Text } from "react-native";
import { renderNavigation } from "react-navigation-config";
const baseRoutes = {
app: true,
children: [
{
name: "Home",
component: () => (
<View>
<Text>Hello</Text>
</View>
)
}
]
};
export default renderNavigation(baseRoutes);- index.js
import { AppRegistry } from "react-native";
import App from "./App";
import { name as appName } from "./app.json";
AppRegistry.registerComponent(appName, () => App);TabLayout Example
- index.js
import React from "react";
import { AppRegistry, View, Text } from "react-native";
import { renderNavigation } from "react-navigation-config";
import { name } from "./app";
class Tab1 extends React.Component {
render() {
return (
<View>
<Text>Tab1</Text>
</View>
);
}
}
class Tab2 extends React.Component {
render() {
return (
<View>
<Text>Tab2</Text>
</View>
);
}
}
const App = renderNavigation({
app: true,
all: [
{
name: "tab2",
component: Tab2
},
{
name: "tab1",
component: Tab1
}
],
routerConfig: {
initialRouteName: "tab1"
}
});
AppRegistry.registerComponent(name, () => App);
Configuration
Route object with the properties.
<Boolean>app- call function createAppContainer at last, return a AppContainer wrapper.<String>name- route name, optional, use random name if not specified, for use this.props.navigation.navigate(routeName), is not necessary when app is"true"<String>path- optional, deep linking<Object>routerConfig- read document related to StackNavigatorConfig,SwitchNavigatorConfig...<Object>navigationOptions- set parameter navigationOptions in RouteConfigs when injectNavigationOptions not specified<Object>screenProps- route meta fields,will be integrated into screenProps<Function>use- other navigation container creator, use default setting if null.
import { createMaterialBottomTabNavigator } from "react-navigation-material-bottom-tabs";
// config
{
name: "tab",
use: createMaterialBottomTabNavigator,
navigationOptions: {
header: null
},
all: [ ... ]
}<Boolean | String>injectNavigationOptions- this option is not necessary, inject static variable navigationOptions into the component's class, it is available when one of following values:true: direct injection"extend": inherit first then inject
only one of following options can be choose:
Array<Route>children- create as StackNavigatorArray<Route>all- create BottomTabNavigatorArray<Route>oneOf- create as SwitchNavigatorArray<Route>drawer- create as DrawerNavigator
API
filterNavigation(routes, allows)
remove route config by name where the array allows not contain.
Parameters
Array<Route>routes - the route configurationArray<String>allows - route names that will be reservedArray<String>- optional, container constructor fields, ["children", "all", "oneOf", "drawer", ...]
filterNavigation(
[{"children":[{"name":"A","children":[{"name":"C"}]},{"name":"B"},{"name":"D","children":[{"name":"E"}]}]}],
["C", "B"]
)output:
[{"children":[{"name":"A","children":[{"name":"C"}]},{"name":"B"}]}]renderNavigation(routes,navigator,fields)
create navigation components with config.
Parameters
Array<Route>routes - the route configuration<Navigator> navigator- the navigator that will be initialized
wrappedNavigatorRef
receive a navigator that can navigate to specified route anywhere.
Parameters
Array<Route>AppContainer - from call renderNavigation<Navigator> navigator- optional, the navigator that will be initialized, use default navigator if not specify
linkNavigatorProvider
4.x preview, define navigation container constructor.
Parameters
<String>type - config field name of navigator constructor<Navigator> navigator- constructor
import { createStackNavigator } from 'react-navigation-stack';
linkNavigatorProvider("all", createStackNavigator);Navigator
send some frequent actions to router use the method provided by the navigator.
Custom Navigator
- create and export a navigator object
// navigator.js
import { Navigator } from "react-navigation-config";
export default new Navigator();- init with wrappedNavigatorRef
import navigator from "./navigator"; // navigator.js
// ....config
const routes = { ... };
export default wrappedNavigatorRef(renderNavigation(routes,navigator), navigator);- import anywhere
import React from "react";
import { Button, View } from "react-native";
import navigator from "./navigator"; // navigator.js
export default class extends React.Component {
navigateTest= () => {
navigator.navigateTo("home").then(() => {
// navigation state changed
});
};
render() {
return (
<View>
<Button
title="Navigate Test"
onPress={this.navigateTest}
/>
</View>
);
}
}Default Navigator
export default wrappedNavigatorRef(renderNavigation(routes));import router from "react-navigation-config/router"
export default class extend React.Component
{
handleEvent()
{
router.navigateTo(.....);
}
...
}Navigator API
navigateTo
update the navigation state with the given name and options.
Parameters
<String> name- required<Object> options- optional
options - following navigator methods are the same
<Object> params- optional, the params field of navigation prop state
<Object> channel- optional, will be integrated toscreenProps, can pass any objects, including functions that interact between screens, but use for pop action may be very dangerous.
<String>routeKey- optional
Return Value
<Promise>- resolve when successful for action
import { NavigationActions } from 'react-navigation';
this.props.navigation.dispatch(NavigationActions.navigate({
routeName: 'Profile',
params: {},
action: NavigationActions.navigate({ routeName: 'SubProfileRoute' }),
}));is similar with
router.navigateTo("Profile",{}).then(async ()=>{
await router.navigateTo("SubProfileRoute");
});reLaunch
wipes the whole navigation state.
Parameters
<String> name- required, route name that will replace first screen.<Object> options- optional
Return Value
<Promise>
redirectTo
replace the route at the given name with another.
Parameters
<String> name- required<Object> options- optional
Return Value
<Promise>
beforeEach
register interceptor before state change.
Parameters
<Function>- callback
router.beforeEach((action, to, from, next) => {
if(from.routeName==="main")
{
next("home",{});
}
});callback
<Object>action- navigation action<Object>to- route state<Object>from- current route state<Function>next(routeName,options)- action create helper, if fieldparamsof parameter options isundefined,it will be ignored and unchanged.
options.routeName- optionaloptions.action- optional, NavigationActions.navigate(...)options.params- optionaloptions.channel- optional, not recommended here
next - action create helper
next()- nothing happennext(false)- abort current navigationnext(routeName:String,options:Object)- navigate to new onenext(options:Object)- navigate to new one, omit the parameter routeName, but need to specific action or routeName in parameteroptions
beforeResolve
handle URIs event.
Parameters
<Function>- callback
callback
<Object>state<Object>to<String>path- deep link path<String>params- query param and path param<Object>next(routeName,params)- action rewrite helper
router.beforeResolve((state, to, path, params, next) => {
// authorization code here ....
next(action.routeName, {
params: {
...params
}
});
});beforeBackward
register listener for backward actions.
Parameters
<Function>- callback
router.beforeBackward((action, to, from) => {
const {params, routeName} = from;
// do something
});onReady
navigation initialized.
Parameters
<Function ((void)=>void)>- callback
Return Value
void
afterEach
register a listener after state change.
Parameters
<Function (action,to,form)=>void>- callback
Return Value
void
preventDefaultActionFix
it is not work default.
Parameters
<Boolean>disabled
try call preventDefaultActionFix(false) to enable it.
Problem
const A = createStackNavigator({ B:... })
const C = createSwitchNavigator({C:A});
...
this.props.navigation.disptach(
NavigationActions.navigate({ routeName: 'A',params:{xyz:100} })
);navigate to route A, actually redirect to B ,but params "xyz" passed to route A.
get params from props.navigation.state is always undefinded in component B.
Fixed
redirect to child route when action.routeName not equal to the state resolved.
preventDefaultURIResolveFix
Parameters
<Boolean>disabled
try call preventDefaultURIResolveFix(false) to enable it.
Problem
path params will not merge to route params.
// browser
<a href="mychat://main/tab/mine/tom?country=China">Mine</a>
// app route config
createStackNavigator({
mine: {
path: 'mine/:user',
})
},
...MyOtherRoutes,
});path paramter "tom" will not appear in route.params of navigation prop.
Fixed
force merge path params to route.params.
push
Parameters
<String> name- required<Object> options- optional
Return Value
<Promise>
dispatchAction
low-level method, update navigation current state with the given action.
Parameters
<Object> action- navigation action<Object> options- optional, not sure all fields effective.
Return Value
<Promise>
getActiveKey
get current route key.
Parameters
void
Return Value
<String| null>
getActiveName
get current route name.
Parameters
void
Return Value
<String| null>
getParams
get route params by key.
Parameters
<String> key- optional, return current route params if not specified
Return Value
<Object | null>
mergeParams
get all params of the stack.
Parameters
<void> key
Return Value
<Object | null>
setParams
set route params by key.
Parameters
<String> key- optional, use active key if null<String> params- required
Return Value
<Promise>
openDrawer
Parameters
<Object>options- optional
Return Value
<Promise>
closeDrawer
Parameters
<Object>options- optional
Return Value
<Promise>
toggleDrawer
Parameters
<Object>options- optional
Return Value
<Promise>
pop
takes you back to a previous screen in the stack.
options.params is not supported in any go back action.
Parameters
<Object> n- the number of screens<Object | null> options- optional
Return Value
<Promise>
popToTop
takes you back to the first screen in the stack.
Parameters
<Object | null> options- optional
Return Value
<Promise>
navigateBack
go back to previous screen and close current screen.
Parameters
<Object>options- optional
Return Value
<Promise>
getChannel
Parameters
<String> key- optional
import router from "react-navigation-config/router";
class ScreenA extends React.Component
{
state={n:0};
add=()=>{ this.setState({n:this.state.n+1}) };
onBtnNavigateClick=()=>{
router.navigateTo("B",{ channel:{ add:this.add } })
}
...
}
// ScreenB
class ScreenB extend React.Component
{
onTest=()=>{
const {add} = router.getChannel();
add(); // update ScreenA state
}
render()
{
return <Button title="test" onPress={this.onTest} />
}
}
Return Value
<Object | null>
updateChannel
Parameters
<String | null > key- required<Object> channel- required
Return Value
<Boolean>
import router from "react-navigation-config/router";
import { Button } from "react-native";
export default class A extends React.Component()
{
static navigationOptions = () => {
const onPress = () => {
const channel = router.getChannel(); // or use mergeChannels
channel.handleSave();
};
return {
headerRight: <Button title={"Save"} onPress={onPress} />
};
};
// set header button callback
componentDidMount() { // or constructor
router.updateChannel(null, { handleSave:()=>console.log("saved!") });
}
}removeChannel
Parameters
<String | null > key- required
Return Value
<void>
mergeChannels
merge channels of state, fields of channels with the same name will be overridden.
Parameters
<void>
Return Value
<Array<object>>
const [stackChannels] = router.mergeChannels();
const { ... } = stackChannels;channelProvider
create a component that receive the channel data.
Parameters
navigation- required
Return Value
React Component
import router from "react-navigation-config/router";
export default class extends React.Component {
static navigationOptions = ({ navigation }) => {
const onPress = () => {
const channel = router.getChannel();
channel.handleHeaderRight();
};
const ChannelProvider = router.channelProvider(navigation);
return {
headerRight: (
<ChannelProvider>
{props => {
const { showSaveBtn } = props;
// show or hide buttons based on channel data
return showSaveBtn ? (
<Button title={"Save"} onPress={onPress} />
) : null;
}}
</ChannelProvider>
)
};
};
state = {
data: 100
};
toggleHeaderButton = () => {
const channel = router.getChannel();
router.updateChannel(null, {
handleHeaderRight: () => {
console.log(this.state);
},
showSaveBtn: !channel.showSaveBtn
});
};
render() {
return (
<View>
<Button
title="Toggle Header Button"
onPress={this.toggleHeaderButton}
/>
</View>
);
}
}hasPreviousNavigation
Parameters
<String | null> routeKey- required<Number> depth- optional, stack depth for comparison , default 0
Return Value
Boolean
import router from "react-navigation-config/router";
// custom header shows or hides the back button automatically
export default CustomerHeader = () => {
return {router.hasPreviousNavigation(null) ? <Icon type="MaterialIcons" name="arrow-back"/> : null}
}Decorator
navigationOptions(options)
set static navigationOptions variable in subclass.
Parameters
Objectoptions - see createStackNavigator or others
