如何将渲染的组件保存到内存中?

时间:2017-07-14 21:36:37

标签: javascript reactjs caching react-native rendering

我正在开发一个由多个屏幕组成的React Native应用程序(尽管我认为我的问题一般适用于React)。

所以我创建了一个简单的组件来切换屏幕:

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包含屏幕列表,this.props.route包含需要显示的路径。该组件工作正常,但我的问题是我想缓存到某些屏幕的内存,因为它们渲染速度很慢(一个大的列表),并且当React重新渲染它们时它们会丢失滚动位置。

在上面的示例中,我尝试将渲染保存到this.screenCache_,但这可能不是正确的方法,因为当我加载它们时屏幕仍然会重新渲染,转到另一页,然后回到他们身边。

我认为这是一个常见问题,但我无法在Google上找到任何相关信息。有关如何做到这一点的任何建议吗?

3 个答案:

答案 0 :(得分:4)

没有办法以你的方式有效地缓存组件,因为DOM后来仍然需要重新绘制它,这是重要的部分。

一个更简单的解决方案,我认为松弛就是使用display: none代替。

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

PS。如果当前未显示该组件以避免性能问题,您可能需要将shouldComponentUpdate设置为false

答案 1 :(得分:1)

你的第一个答案不应该是在React中缓存内容。还有很多其他方法可以提高性能。首先阅读文档的性能部分。有一些非常简单的解决方案可以立即提高性能。

React Native Documentation: Performance

您可以采取其他一些措施来提高绩效:

  1. 删除console.logs和其他记录器。
  2. 使用componentShouldUpdate确保您只在需要时重新渲染。
  3. 如果您使用的是redux,请查看选择器。如果您有需要计算的数据并且您正在进行不必要的重复计算,则可以记住该数据。
  4. 我认为您的问题来自React Native文档中的某些内容,所以在尝试执行过于复杂的操作之前先执行这些操作。

    作为参考点,我的一个朋友最近做了一个VR应用程序,进行多次计算,每次陀螺仪移动时更新redux状态,并在DOM上每秒重新渲染数百次。 React Native可以占用很多,所以不用担心缓存。

答案 2 :(得分:0)

听起来你需要一个导航库来处理屏幕。查看https://reactnavigation.org

例如,使用具有两个路径的StackNavigator,即列表和详细信息。

const app = StackNavigator({
  Index: { screen: Some list view },
  Detail: { screen: some detail page },
});

此外,如果ListView对您来说很慢,请尝试从0.43开始可用的新FlatList或SectionList组件。他们的表现更为出色。