Possible navigation issue in React Native / Redux app

During navigation in the Big React Native app using Redux, all visited scenes (scenes from the navigation stack) remain in place. All these scenes receive props and are visualized in the order in which they were visited when any action was sent from the last component of the scene. This causes freezes and visible delays between submitting and rendering the last scene.

I use react-native-router-flux for navigation, but the same problem occurs with the original React Navigation Navigator.

Video Possible navigation issues with React Native / Redux

React-redux-navigation-test code

It would be nice to know how to prevent the transfer of props to unfocused components from the navigation chain.

At the moment I am checking ifComponentUpdate of each component if this object is focused (visible) and returns false otherwise.

Is there a better solution?

+6
source share
5 answers

I recommend that you calculate the distance of the scene between the current scene and the scene displayed using the navigation index in the scene and title rendering methods. If distance> 1 returns zero.

This should prevent the entire navigation history from being displayed. It does not seem to me that such behavior is not available out of the box, but it does exist.

+2
source

I have not used the native-router-flux reaction flow, however I have experience with the fairly large React Native and Redux. I noticed that sometimes, if the data you are working with becomes large enough, this can cause noticeable delays, but mostly they are limited to work in development. When an application is built, it is usually noticeably faster. Redux seems to do things a little differently in development and production modes.

As for the scenes in the navigation stack that are still mounted, that is, by design. Even when you navigator.push on another screen, these previous screens remain set until they slip out of currentRouteStack or replaced with currentRouteStack .

In addition, it may be worth noting that your simulator is in slow animation mode. Not sure if you did it for the sake of the video or not, but this is partly due to the slow navigation. Just heads-up in case it wasnโ€™t on purpose.

I would see how the application works after you built it, and not in development mode, before fixing performance issues. It may not be a problem for the final product of the application.

0
source

I'm going to go limb here, but are you using one of the following methods to prevent re-rendering?

  • PureComponents (added in React 15.3, I think)
  • Manually with details with incomplete comparison and status using the toComponentUpdate method.

By default, React will re-render all components when upgrading if you do not handle mustComponentUpdate correctly.

I am doing something similar and donโ€™t have these problems at all

0
source

The problem is that the entire navigation stack is connected to the repository (since the components are not unmounted unless you use resetto or resetnavigation)

For what stands here is what I am doing right now. I worked with a slightly modified implementation of reaction reduction, which skips updates for scenes that are not displayed (see below).

To use it, you need:

Saving a route for a single 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 the rendering area

 <CurrentRoute route={route}><CurrentScene navigate={navigate} route={route} index={index} /></CurrentRoute> 

You can then access the route to which the component was added.

Keep the navigation stack in singleton mode. We use this code in the scene configuration.

 let routeStack = []; export const updateRouteStack = stack => routeStack = stack; 

Then you can use this slightly modified connect-redux connect function, it skips updates if the component is displayed in another component tree and then displayed (or a similar implementation) https://github.com/reactjs/react-redux/compare/master ... ganmor: master

It may be possible to pack it, but I did not have time to study it. If anyone wants to do this .. Hope that helps

0
source

We solved this by simply wrapping all the screens in a component.

We have one ScreenView component that wraps the entire screen, and we pass the parameter "limitRerendersToRoutes" to it.

This screen is connected to a state, and we update currentScrene in our state and show it on this screen.

Then we simply restrict rerenders when the screen is in the background with this implementation of shouldComponentUpdate:

  shouldComponentUpdate(nextProps) { if (!_.empty(this.props.restrictRerendersToRoutes)) { return !!this.props.restrictRerendersToRoutes .find((routeKey) => routeKey === nextProps.currentScene.name); } return true; } 
0
source

All Articles