2017-01-26 11:49:39 -08:00
# Routers
Routers define a component's navigation state, and they allow the developer to define paths and actions that can be handled.
## Built-In Routers
`react-navigation` ships with a few standard routers:
- [StackRouter ](/docs/routers/stack )
2017-05-13 06:36:53 +09:00
- [TabRouter ](/docs/routers/tab )
2017-01-26 11:49:39 -08:00
## Using Routers
To make a navigator manually, put a static `router` on a component. (To quickly make a navigator with a built-in component, it may be easier to use a [Navigator Factory ](/docs/navigators ) instead)
```js
class MyNavigator extends React.Component {
static router = StackRouter(routes, config);
...
}
```
Now you can use this component as a `screen` in another navigator, and the navigation logic for `MyNavigator` will be defined by this `StackRouter` .
## Customizing Routers
See the [Custom Router API spec ](/docs/routers/api ) to learn about the API of `StackRouter` and `TabRouter` . You can override the router functions as you see fit:
### Custom Navigation Actions
To override navigation behavior, you can override the navigation state logic in `getStateForAction` , and manually manipulate the `routes` and `index` .
```js
const MyApp = StackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
}, {
initialRouteName: 'Home',
})
2017-04-24 18:27:06 +02:00
const defaultGetStateForAction = MyApp.router.getStateForAction;
MyApp.router.getStateForAction = (action, state) => {
if (state & & action.type === 'PushTwoProfiles') {
const routes = [
...state.routes,
{key: 'A', routeName: 'Profile', params: { name: action.name1 }},
{key: 'B', routeName: 'Profile', params: { name: action.name2 }},
];
return {
...state,
routes,
index: routes.length - 1,
};
}
return defaultGetStateForAction(action, state);
2017-01-26 11:49:39 -08:00
};
```
### Blocking Navigation Actions
Sometimes you may want to prevent some navigation activity, depending on your route.
```js
const MyStackRouter = StackRouter({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
}, {
initialRouteName: 'Home',
})
2017-04-24 18:27:06 +02:00
const defaultGetStateForAction = MyStackRouter.router.getStateForAction;
MyStackRouter.router.getStateForAction = (action, state) => {
if (
state & &
action.type === NavigationActions.BACK & &
state.routes[state.index].params.isEditing
) {
// Returning null from getStateForAction means that the action
// has been handled/blocked, but there is not a new state
return null;
}
return defaultGetStateForAction(action, state);
2017-01-26 11:49:39 -08:00
};
```
### Handling Custom URIs
Perhaps your app has a unique URI which the built-in routers cannot handle. You can always extend the router `getActionForPathAndParams` .
```js
2017-02-01 16:27:51 -05:00
import { NavigationActions } from 'react-navigation'
2017-01-26 11:49:39 -08:00
const MyApp = StackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
}, {
initialRouteName: 'Home',
})
2017-04-24 18:27:06 +02:00
const previousGetActionForPathAndParams = MyApp.router.getActionForPathAndParams;
2017-03-16 23:35:53 +01:00
Object.assign(MyApp.router, {
2017-01-26 11:49:39 -08:00
getActionForPathAndParams(path, params) {
if (
path === 'my/custom/path' & &
params.magic === 'yes'
) {
// returns a profile navigate action for /my/custom/path?magic=yes
2017-02-01 16:27:51 -05:00
return NavigationActions.navigate({
2017-01-26 11:49:39 -08:00
routeName: 'Profile',
2017-02-01 16:27:51 -05:00
action: NavigationActions.navigate({
2017-01-26 11:49:39 -08:00
// This child action will get passed to the child router
// ProfileScreen.router.getStateForAction to get the child
// navigation state.
routeName: 'Friends',
2017-02-01 16:27:51 -05:00
}),
});
2017-01-26 11:49:39 -08:00
}
2017-03-16 23:35:53 +01:00
return previousGetActionForPathAndParams(path, params);
2017-01-26 11:49:39 -08:00
},
};
```