Reputation: 90834
I'm developing a React Native application (although I think my issue applies to React in general) made of multiple screens.
So I've created a simple component to switch the screens:
import React, { Component } from 'react';
import { connect } from 'react-redux'
import { View } from 'react-native';
class AppNavComponent extends Component {
constructor() {
super();
this.screenCache_ = {};
}
render() {
if (!this.props.route) throw new Error('Route must not be null');
let route = this.props.route;
if (this.screenCache_[route.routeName]) return this.screenCache_[route.routeName];
let Screen = this.props.screens[route.routeName].screen;
this.screenCache_[route.routeName] = (
<View>
<Screen/>
</View>
);
return this.screenCache_[route.routeName];
}
}
const AppNav = connect(
(state) => {
return {
route: state.route,
};
}
)(AppNavComponent)
export { AppNav };
this.props.screens
contains the list of screens, and this.props.route
the route that needs to be displayed. The component works fine, but my problem is that I'd like to cache to memory certain screens because they are slow to render (a large list) and they lose the scrolling position whenever React re-render them.
In the example above, I've tried to save the rendering to this.screenCache_
but that's probably not the right approach as the screens are still re-rendering when I load them, go to another page, and go back to them.
I guess that's a common problem but I can't find any information on Google. Any suggestion on how to do this?
Upvotes: 6
Views: 3640
Reputation: 1291
Sounds like you need a navigation library to handle screens. Check https://reactnavigation.org
For example, use a StackNavigator with two routes, i.e. list and detail.
const app = StackNavigator({
Index: { screen: Some list view },
Detail: { screen: some detail page },
});
Also if the ListView is slow for you, try the new FlatList or SectionList component that’s available since 0.43. They are more performant.
Upvotes: 0
Reputation: 2050
Your first answer shouldn't be to cache things in React. There are a lot of other ways to increase performance. Start by reading the performance section of their documentation. There are some very simple solutions to increase performance right off the bat.
React Native Documentation: Performance
Some other things you can do to increase performance:
I think that your problem comes from something from the React Native docs so run through those things first before trying to do things overly complicated.
For a point of reference, one of my buddies recently made a VR application doing multiple calculations that updated redux state every time the gyroscope moved and rerendered objects on the DOM hundreds of times per second. React Native can take a lot so don't worry about caching yet.
Upvotes: 1
Reputation: 20037
There's no way to efficiently cache the component in the way you go about it, because the DOM still would need to repaint it later, which is the heavy part.
A simpler solution, and I think slack does that under the hood, is to use display: none
instead.
<View style={shouldDisplayScreen ? {} : { display: none }} />
PS. You might want to set shouldComponentUpdate
to false
, if the component is currently not being displayed to avoid performance issues.
Upvotes: 6