Skip to content

Instantly share code, notes, and snippets.

@cpsubrian
Last active July 11, 2016 18:10
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 cpsubrian/278ad43f79f2301c4aba1cb5401fca99 to your computer and use it in GitHub Desktop.
Save cpsubrian/278ad43f79f2301c4aba1cb5401fca99 to your computer and use it in GitHub Desktop.
react-router-native dynamic header via redux
export const MERGE_CONF = 'core.app.merge_conf'
export function mergeConf (conf) {
return {type: MERGE_CONF, conf}
}
import React from 'react'
import {View, Image, Text, TouchableHighlight} from 'react-native'
import {Link} from 'react-router-native'
import Scene from 'core/components/scene/Scene'
import styles from './HomeScene.styles'
class HomeScene extends React.Component {
render () {
return (
<Scene title='Home'>
<View style={[styles.scene, styles.homeScene]}>
<Link to='/states' style={styles.space}>
<Text style={styles.h1}>States --></Text>
</Link>
</View>
</Scene>
)
}
}
export default HomeScene
const routes = (
/* Address Bar can be toggled on or off by setting the addressBar prop */
<Router history={nativeHistory} addressBar>
<TabsRoute path="app" component={App}>
<Route path='/' component={HomeScene} overlayComponent={NavigationHeader}/>
<Route path='/states' component={StatesScene} overlayComponent={NavigationHeader}/>
</TabsRoute>
<Route path="*" component={NoMatch}/>
</Router>
);
AppRegistry.registerComponent('YourApp', () => () => routes);
import React from 'react'
import autobind from 'autobind-decorator'
import {connect} from 'react-redux'
import {NavigationExperimental, Text} from 'react-native'
import {Pop} from 'react-router-native'
import {sceneSelector} from 'core/selectors/scene'
import baseStyles from './NavigationHeader.styles'
@connect(sceneSelector)
@autobind
export default class NavigationHeader extends React.Component {
static propTypes = {
// Main Props.
styles: React.PropTypes.object,
style: React.PropTypes.object,
renderLeft: React.PropTypes.func,
renderTitle: React.PropTypes.func,
renderRight: React.PropTypes.func,
// From sceneSelector.
sceneProps: React.PropTypes.object,
// From router.
layout: React.PropTypes.object,
location: React.PropTypes.object,
params: React.PropTypes.object,
navigationState: React.PropTypes.object,
scene: React.PropTypes.object
}
static defaultProps = {
styles: {}
}
renderLeft () {
return this.props.scene.index ? (
<Pop style={[baseStyles.back, this.props.styles.back]}>
<Text style={[baseStyles.backText, this.props.styles.backText]}>
Back
</Text>
</Pop>
) : null
}
renderTitle () {
return this.props.sceneProps.title ? (
<NavigationExperimental.Header.Title
style={[baseStyles.title, this.props.styles.title]}
textStyle={[baseStyles.titleText, this.props.styles.titleText]}
>
{this.props.sceneProps.title}
</NavigationExperimental.Header.Title>
) : null
}
render () {
let {styles, style, renderTitle, renderLeft, renderRight, sceneProps, ...rest} = this.props
return (
<NavigationExperimental.Header
style={[baseStyles.header, this.props.styles.header, this.props.style]}
renderLeftComponent={renderLeft || this.renderLeft}
renderTitleComponent={renderTitle || this.renderTitle}
renderRightComponent={renderRight || undefined}
{...rest}
/>
)
}
}
import Immutable from 'immutable'
import {
MERGE_PROPS
} from 'core/actions/scene'
const initialState = Immutable.fromJS({
props: {}
})
const reducers = {
[MERGE_PROPS]: (state, {props}) => {
return state.mergeIn(['props'], props)
}
}
export default {name: 'scene', initialState, reducers}
import React from 'react'
import _ from 'lodash'
import {connect} from 'react-redux'
import {mergeProps} from 'core/actions/scene'
@connect(null, {mergeProps})
class Scene extends React.Component {
static propTypes = {
title: React.PropTypes.string,
mergeProps: React.PropTypes.func,
children: React.PropTypes.node
}
componentDidMount () {
this.props.mergeProps(_.omit(this.props, 'mergeProps', 'children'))
}
componentWillReceiveProps (nextProps) {
this.props.mergeProps(_.omit(nextProps, 'mergeProps', 'children'))
}
render () {
return this.props.children
}
}
export default Scene
import {createSelector} from 'reselect'
export const sceneSelector = createSelector(
(state) => state.scene,
(scene) => {
return {
sceneProps: scene.get('props').toJS()
}
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment