How do I keep the mapped component in memory?

I am developing a React Native app (although I think my problem is related to React in general) made of multiple screens.

So, I created a simple component to switch 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 the this.props.route

route to be displayed. The component works fine, but my problem is that I would like to cache certain screens in memory because they are slow to render (large list) and they lose the scroll position whenever React re-renders them.

In the example above, I tried to keep the rendering on this.screenCache_

, but this is probably not the correct approach as the screens are still redrawn when loading, navigating to another page, and returning to them.

I guess it's a general problem, but I can't find any information on Google. Any suggestion on how to do this?

+3


source to share


3 answers


It is not possible to efficiently cache a component the way you do it because the DOM will still have to redraw it later, which is the hard part.

A simpler solution, and I think the slack makes it under the hood, should be used instead display: none

.

<View style={shouldDisplayScreen ? {} : { display: none }} />




PS. You might want to set shouldComponentUpdate

to false

if the component is not currently visible to avoid performance issues.

+3


source


Your first answer shouldn't be about caching things in React. There are many other ways to improve productivity. Start by reading the performance section of your documentation. There are some very simple solutions to improve productivity right from the start.

Real source documentation: performance

Some other things you can do to improve performance:



  • Remove console.log files and other logs.
  • Use componentShouldUpdate to ensure that re-renders only when you need to.
  • If you are using redux take a look at Selectors. If you have data that needs to be calculated and you are doing unnecessary repetitive calculations, you can memoize that data.

I think your problem is coming from something from the React Native docs, so try these things first before trying to do something too complicated.

At one point, one of my buddies recently made a VR app doing a few computations that updated the state of the reduct every time the gyroscope moved and re-rendered objects to the DOM hundreds of times per second. React Native can take a lot, so don't worry about caching.

+1


source


It looks like you need a navigation library to handle screens. Check out https://reactnavigation.org

For example, use a StackNavigator with 2 routes i.e. list and details.

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 available since 0.43. They are more efficient.

0


source







All Articles