Nader Dabit
Ships with React Native
From the Community
Current State of Native Implementations
NavigatorIOS
PROS
Current State of Native Implementations
NavigatorIOS
CONS
NavigatorIOS
Creating an instance of NavigatorIOS
import {
...
NavigatorIOS
} from 'react-native'
1. Import NavigatorIOS from React Native
2. Create or import an initial route
import Home from '../pathtohome'
3. Return the Navigator in render
render () {
return (
<NavigatorIOS
initialRoute={{
component: Home,
title: 'Home'
}} />
)
}
NavigatorIOS
Pushing and popping to the route stack
this.props.navigator.push({
component: About,
title: 'About'
})
this.props.navigator.pop()
2. Popping to a previous route (go back)
1. Pushing to a new route
NavigatorIOS
Pushing and popping to the route stack
this.props.navigator.push({
component: About,
title: 'About',
passProps: {
name: 'React Camp',
city: 'New York'
}
})
Passing properties
Current State of Native Implementations
Navigator
PROS
Current State of Native Implementations
Navigator
CONS
Navigator
Creating an instance of Navigator
import {
...
Navigator
} from 'react-native'
1. Import Navigator from React Native
2. Create or import an initial route
import Home from '../pathtohome'
3. Create renderScene method
renderScene (route, navigator) {
return <route.component
navigator={navigator}
{...route.passProps} />
}
Navigator
Return instance of Navigator:
<Navigator
renderScene={this.renderScene.bind(this)}
initialRoute={{
component: Home
}} />
Pushing and popping to the route stack:
this.props.navigator.push({
component: About
})
this.props.navigator.pop()
2. Popping to a previous route (go back)
1. Pushing to a new route
Navigator
<Navigator
configureScene={this.configureScene.bind(this)}
renderScene={this.renderScene.bind(this)}
initialRoute={{
component: Home
}} />
configureScene (route) {
if (route.type === 'modal') {
return Navigator.SceneConfigs.FloatFromBottom
}
return Navigator.SceneConfigs.FloatFromRight
}
1. Create configureScene method (available options)
2. Attach it to the navigator
this.props.navigator.push({
...
type: 'modal'
})
3. Pass type of modal when we want a modal
Current State of Native Implementations
Navigator Experimental
Navigator Experimental
Creating an instance of Navigator Experimental
Navigator Experimental
Creating an instance of Navigator Experimental
import React from 'react'
import { AppRegistry } from 'react-native'
import configureStore from './app/store/configureStore'
const store = configureStore()
import NavigationRootContainer from './app/containers/navRootContainer'
import { Provider } from 'react-redux'
const App = () => (
<Provider store={store}>
<NavigationRootContainer />
</Provider>
)
AppRegistry.registerComponent('RNComprehensiveNavigation', () => App)
Entrypoint (index.ios.js / index.android.js)
Navigator Experimental
Creating an instance of Navigator Experimental
import { POP_ROUTE, PUSH_ROUTE } from '../constants/ActionTypes'
export function push (route) {
return {
type: PUSH_ROUTE,
route
}
}
export function pop () {
return {
type: POP_ROUTE
}
}
actions/actions.js
Navigator Experimental
Creating an instance of Navigator Experimental
import { PUSH_ROUTE, POP_ROUTE } from '../constants/ActionTypes'
const initialState = {
index: 0,
key: 'root',
routes: [{ key: 'home', title: 'Home' }]
}
export default (state = initialState, action) => {
switch (action.type) {
case PUSH_ROUTE:
return {
...state,
routes: [
...state.routes,
action.route
],
index: state.index + 1
}
case POP_ROUTE:
return state.index > 0 ? {
...state,
routes: state.routes.slice(0, state.routes.length - 1),
index: state.index - 1
} : state
default:
return state
}
}
reducers/navReducer.js
Navigator Experimental
Creating an instance of Navigator Experimental
import { connect } from 'react-redux'
import { push, pop } from '../actions/navActions'
import NavigationRoot from '../components/NavRoot'
function mapStateToProps (state) {
return {
navigation: state.navReducer
}
}
function mapDispatchToProps (dispatch) {
return {
pushRoute: (route) => dispatch(push(route)),
popRoute: () => dispatch(pop())
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(NavigationRoot)
navRootContainer.js
Navigator Experimental
Creating an instance of Navigator Experimental
import React, { Component } from 'react'
import Home from './Home'
import About from './About'
import {
NavigationExperimental
} from 'react-native'
const {
CardStack: NavigationCardStack
} = NavigationExperimental
containers/navigationRoot.js
Navigator Experimental
_renderScene (props) {
const { route } = props.scene
if (route.key === 'home') {
return <Home _handleNavigate={this._onNavigate.bind(this)} />
}
if (route.key === 'about') {
return <About _goBack={this.props.popRoute.bind(this)} />
}
}
containers/navRoot.js - renderScene
{
key: 'home',
title: 'Home'
}
props.scene.route
routes: [{
key: 'home',
title: 'Home'
}]
reducer initial route array
Navigator Experimental
_onNavigate (action) {
switch (action.type) {
case 'push':
this.props.pushRoute(action.route)
return true
case 'pop':
this.props.popRoute()
return true
default:
return false
}
}
containers/navRoot.js - renderScene
Navigator Experimental
render () {
return (
<NavigationCardStack
navigationState={this.props.navigation}
onNavigate={this._onNavigate.bind(this)}
renderScene={this._renderScene.bind(this)} />
)
}
rendering the NavigationCardStack component
React Native Navigation
Community / Open Source implementations
React Native Navigation
Community / Open Source implementations
import { Navigation } from 'react-native-navigation'
import { registerScreens } from './screens'
registerScreens()
Navigation.startTabBasedApp({
tabs: [
{
label: 'One',
screen: 'FirstTabScreen',
icon: require('./img/one.png'),
selectedIcon: require('./img/one_selected.png'),
title: 'Scrseen One'
},
{
label: 'Two',
screen: 'SecondTabScreen',
icon: require('./img/two.png'),
selectedIcon: require('./img/two_selected.png'),
title: 'Screen Two'
}
]
})
npm i react-native-navigation --save
React Native Navigation
import { Navigation } from 'react-native-navigation';
import FirstTabScreen from './FirstTabScreen';
import SecondTabScreen from './SecondTabScreen';
import PushedScreen from './PushedScreen';
export function registerScreens() {
Navigation.registerComponent('FirstTabScreen', () => FirstTabScreen);
Navigation.registerComponent('SecondTabScreen', () => SecondTabScreen);
Navigation.registerComponent('PushedScreen', () => PushedScreen);
}
screens.js
navigate () {
this.props.navigator.push({
screen: 'PushedScreen'
})
}
push route
this.props.navigator.pop()
pop route
Community / Open Source implementations
React Native Simple Router
Community / Open Source implementations
React Native Simple Router
npm install react-native-simple-router --save
import Router from 'react-native-simple-router'
import Home from './Home'
const firstRoute = {
name: 'Home!',
component: Home
}
class RNComprehensiveNavigation extends Component {
render() {
return (
<Router
firstRoute={firstRoute}
headerStyle={styles.header} />
)
}
}
Community / Open Source implementations
React Native Simple Router
this.props.toRoute({
name: 'About',
component: About,
passProps: {
title: 'Hello From React Camp'
}
})
this.props.toBack()
Basic navigator methods
Community / Open Source implementations
React Native Router Flux
Community / Open Source implementations
React Native Router Flux
npm i react-native-router-flux --save
import React from 'react'
import { AppRegistry } from 'react-native'
import {Scene, Router} from 'react-native-router-flux'
import Home from './Home'
import About from './About'
import More from './More'
class RNComprehensiveNavigation extends React.Component {
render() {
return <Router>
<Scene key='root'>
<Scene key='home' component={Home} title='Home' />
<Scene key='about' component={About} title='About'/>
<Scene key='more' component={More} title='More'/>
</Scene>
</Router>
}
}
React Native Router Flux
import { Actions } from 'react-native-router-flux'
Actions.about()
Actions.home()
Actions.more()
Actions.pop()
// Pass Props
Actions.more({
firstName: 'Nader',
lastName: 'Dabit',
conference: 'React Camp'
})
Scenes
<Scene key='home' component={Home} title='Home' />
<Scene key='about' component={About} title='About'/>
<Scene key='more' component={More} title='More'/>
Methods
Pass all props with passProps boolean
<Scene key='home' component={Home} title='Home' passProps />
Community / Open Source implementations
ExNavigation by Exponent
ExNavigation
npm i @exponent/ex-navigation babel-preset-react-native-stage-0 --save
Router (Create app Routes)
import {
createRouter
} from '@exponent/ex-navigation';
import Home from './Home'
import About from './About'
const Router = createRouter(() => ({
home: () => Home,
about: () => About,
}));
export default Router
import Router from './Router'
import {
NavigationProvider,
StackNavigation,
} from '@exponent/ex-navigation';
const App = () => (
<NavigationProvider router={Router}>
<StackNavigation
defaultRouteConfig={{
navigationBar: {
backgroundColor: '#000',
tintColor: '#fff',
}
}}
initialRoute={Router.getRoute('home')} />
</NavigationProvider>
)
ExNavigation
StackNavigation Component
import Router from './Router'
const people = ['amy', 'matt', 'leslie']
export default class Home extends Component {
static route = {
navigationBar: {
title: 'Home',
}
}
_goToAbout = () => {
this.props.navigator.push(Router.getRoute('about', {people}));
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to Home
</Text>
<TouchableHighlight onPress={this._goToAbout}>
<Text>Go to About</Text>
</TouchableHighlight>
</View>
);
}
}
Home Component
ExNavigation
class SignOutButton extends Component {
render() {
return (
<TouchableOpacity onPress={() => console.log('hello')}>
<Text style={{marginRight: 15, marginTop: 12, color: 'white'}}>Sign out</Text>
</TouchableOpacity>
);
}
}
export default class About extends Component {
static route = {
navigationBar: {
title: 'About',
renderRight: () => <SignOutButton />
}
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to About
</Text>
{
this.props.people.map((p, i) => {
return <Text key={i}>{p}</Text>
})
}
</View>
);
}
}
About Component
ExNavigation
ExNavigation
Community / Open Source implementations
React Router Native
React Router Native
const Master = (props) => (
<View>
{props.children}
</View>
);
const routes = (
<Router history={nativeHistory} addressBar>
<StackRoute path="master" component={Master}>
<Route path="/" component={Home} overlayComponent={HomeHeader} />
<Route path="/detail/:themeColor"
component={Detail}
overlayComponent={DetailHeader} />
</StackRoute>
</Router>
);
AppRegistry.registerComponent('YourApp', () => () => routes);
React Native Navigation - Takeaways
Comprehensive Navigation in React Native
Nader Dabit
React Native Radio
React Native in Action - Manning Publications