Created
March 29, 2018 16:55
-
-
Save HERRKIN/d719899969975b91784ed8d4a79a7d38 to your computer and use it in GitHub Desktop.
HOC that avoids rendering or update unless necesary when using react-navigation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
import { connect } from 'react-redux' | |
import _ from 'lodash' | |
export const renderer = (route, Wrapped) => | |
class extends Component { | |
shouldComponentUpdate(props) { | |
if (!props.render || this.props.currentRoute === 'DrawerOpen') { return false } | |
const thisProps = JSON.stringify(_.omit(this.props, ['nav', 'navigation', 'screenProps'])) | |
const nextProps = JSON.stringify(_.omit(props, ['nav', 'navigation', 'screenProps'])) | |
return !(nextProps === thisProps) | |
} | |
render() { | |
const { currentRoute } = this.props | |
/* once the stack of components has been visited, when revisiting one of the components | |
react-navigation moounts the whole stack at once, the line below renders null if the | |
route is not the one thats supposed to render the screen */ | |
return (route === currentRoute ? <Wrapped {...this.props} /> : null) | |
} | |
} | |
export const getCurrentRouteName = navigationState => { | |
if (!navigationState) { | |
return null | |
} | |
const route = navigationState.routes[navigationState.index] | |
// dive into nested navigators | |
if (route.routes) { | |
return getCurrentRouteName(route) | |
} | |
return route.routeName | |
} | |
export const RouteConnect = (mapState, mapDispatch) => { | |
this.mapState = route => (state, props) => { | |
const { nav } = state | |
const currentRoute = getCurrentRouteName(nav) | |
if (currentRoute === route) { | |
return { ...mapState(state, props), render: true, currentRoute } | |
} | |
return { ...props, render: false, currentRoute } | |
} | |
return (Wrapped, route) => connect( | |
this.mapState(route), | |
mapDispatch, | |
null, | |
{ renderCountProp: 'renderCounter' }, | |
)(renderer(route, Wrapped)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment