During navigation in big React Native app with using Redux all visited scenes (scenes from navigation stack) are staying mounted. All these scenes receive props and get rendered
I'm going to go out on a limb here but are you using one of the below methods to prevent re-rendering?
By default React will re-render all components upon update unless you correctly handle the shouldComponentUpdate.
I'm doing something similar and not having these issues at all
I recommend that you calculate the scene distance between the current scene and scene being rendered using the navigation index in the scene and header rendering methods. If the distance > 1 return null.
This should prevent rendering the entire navigation history. It doesn't make any sense to me that this kind of behaviour is not available out of the box, but there it is.
We solved it by simply wrapping all screens in a component.
We have one ScreenView component that wraps the whole screen, and we pass it a parameter "restrictRerendersToRoutes".
This screen is connected to the state, and we update the currentScrene in our state and expose it to this screen view.
Then we simply restrict rerenders when the screen is in the background with this shouldComponentUpdate implementation:
shouldComponentUpdate(nextProps) {
if (!_.empty(this.props.restrictRerendersToRoutes)) {
return !!this.props.restrictRerendersToRoutes
.find((routeKey) => routeKey === nextProps.currentScene.name);
}
return true;
}
I have not used the react-native-router-flux, however I do have experience with a fairly large React Native and Redux app. I have noticed that sometimes if the data you are working with gets large enough it can cause noticeable delays, but those are mostly limited to working in development. When the app is built it is usually noticeably faster. It seems as though Redux does things a little differently in development and production modes.
Regarding scenes in the navigation stack still being mounted, that is by design. Even when you navigator.push
to another screen those previous screens remain mounted until they are either popped off the currentRouteStack
or replaced from the currentRouteStack
.
Also, it's probably worth noting that your simulator is in Slow Animations mode. Not sure if you did that for the video sake or not, but the navigation slowness is in part due to that. Just a heads up in case that wasn't on purpose.
I would check how the app seems to function after you've built it and it's not in development mode before troubleshooting the performance issues much further. May not be an issue for the final app product.
The problem is indeed that the whole navigation stack is connected to the store( because components are not unmounted unless you use resetto or resetnavigation )
For what it's worth here is what I do right now. I have been working with a slightly modified react redux implementation that skips updates for scenes that are not in view ( see below )
To use it you need to:
Store the route for one component tree in context
We created a wrapper for this
const CurrentRoute = React.createClass({
childContextTypes : { currentRoute: PropTypes.object },
getChildContext() {
return { currentRoute: this.props.route }
},
render() { return this.props.children; }
})
And use it in render scene
<CurrentRoute route={route}><CurrentScene navigate={navigate} route={route} index={index} /></CurrentRoute>
Then you can access the route a component has been rendered into.
Store the navigation stack in a singleton We use this code in configure scene
let routeStack = [];
export const updateRouteStack = stack => routeStack = stack;
Then you can use this slightly modified react-redux connect function, it will skip updates if component is rendered in another component tree then the currently displayed one ( or a similar implementation ) https://github.com/reactjs/react-redux/compare/master...ganmor:master
It might be possible to package this but I haven't had the time to look into it. If anyone feels like doing it.. Hope that helps