【问题标题】:react native - render big FlatList with numColumnsreact native - 使用 numColumns 渲染大的 FlatList
【发布时间】:2021-06-28 05:12:19
【问题描述】:

当我在屏幕上渲染许多单元格时,FlatList 出现问题。

请先看下图。

假设我们有:

  • 行 x 列 = 80 x 80 = 6400 个单元格的地图
  • 启用和禁用滚动功能的按钮

问题:

  1. 地图渲染超慢,初始视图,应用必须调用 renderItem 大约 2000 次才能允许用户继续操作
  2. 我正在尝试更改 windowSizeinitialNumToRender,但没有帮助
  3. 当用户按下Enable/Disable Scroll 时,即使我将extraData 设置为仅cellList,应用程序也必须再次调用renderItem 大约2000 次

问题是:

  • 如果你们知道针对这种情况的任何解决方案或解决方法,请告诉我。任何想法都会受到欢迎。

提前谢谢你们!

下面是代码:

使用 FlatList 映射

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {useCallback, useState} from 'react';
import {FlatList, StyleSheet, Text, TouchableOpacity, View,} from 'react-native';
import Stack from "./src/Stack";

const generateCell = (cellNumber: number): Array<string> => {

    let table = [];

    for (let j = 0; j < cellNumber; ++j) {
        table.push(String(j));
    }

    return table;
};

const App = () => {

    const [cellList] = useState(generateCell(6400));

    const [scrollable, setScrollable] = useState(true);

    const keyExtractorHorizontal = useCallback((item, index) => item.stackId + '-' + index.toString(), []);

    const keyExtractorVertical = useCallback((item, index) => item.stackId + '-' + index.toString(), []);

    // BUTTON

    const onPress = () => {
        setScrollable(!scrollable);
    }

    // RENDER

    const renderCell = ({index}: { index: number }) => {
        console.log('renderCell called', index);
        return (
            <Stack index={index}/>
        )
    };

    return (
        <View style={styles.container}>
            <TouchableOpacity
                style={styles.buttonContainer}
                onPress={onPress}
            >
                <Text>
                    Enable/Disable Scroll
                </Text>
            </TouchableOpacity>
            <FlatList
                scrollEnabled={scrollable}
                horizontal={true}
                showsHorizontalScrollIndicator={false}
                showsVerticalScrollIndicator={false}
                keyExtractor={keyExtractorHorizontal}
                data={[0]}
                extraData={cellList}
                windowSize={100}
                renderItem={() => {
                    return (
                        <FlatList
                            scrollEnabled={scrollable}
                            removeClippedSubviews={false}
                            showsHorizontalScrollIndicator={false}
                            showsVerticalScrollIndicator={false}
                            keyExtractor={keyExtractorVertical}
                            data={cellList}
                            extraData={cellList}
                            renderItem={renderCell}
                            windowSize={3}
                            numColumns={80}
                            initialNumToRender={10}
                        />
                    );
                }}
            />
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },

    buttonContainer: {
        width: '100%',
        height: 80,

        justifyContent: 'center',
        alignItems: 'center',
    }
});

export default App;

地图内的单元格,我称之为“堆栈”

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React from 'react';
import {View} from 'react-native';

const Stack = (props: {
    index: number
}) => {
    console.log('truly render stack', props.index);
    return (
        <View style={
            {
                height: 60,
                width: 60,
                borderColor: 'black',
                borderWidth: 1,
            }
        }/>
    );
};

export default React.memo(Stack);

【问题讨论】:

  • 我认为在FlatList 中渲染FlatList 不是一个好主意。也许您可以通过单元格的索引使用一些分组逻辑。
  • @kenmistry:感谢您的快速评论。我们将不得不滚动 2 个方向,所以我猜我们无法避免 2 个 ScrollView/FlatList。我也尝试了二维分组逻辑,但没有帮助

标签: javascript typescript react-native


【解决方案1】:

我猜您正在尝试实现虚拟化网格布局,并且由于每个网格大小都相同,您可以在 Flatlist(垂直)中使用numColumns,它将列表划分为该列数。在 Flatlist 中使用 Flatlist 对于较少的数据肯定不是问题,但嵌套的 Flatlist 子计数必须在每个父 Flatlist 上重新计算,这可能是迟缓的问题。

【讨论】:

  • 感谢您提供嵌套的 FlatList 信息。正如你所说,我正在使用 numColumns 。但是,我认为没有办法避免嵌套的 FlatList,因为我需要双向滚动。
猜你喜欢
  • 1970-01-01
  • 2018-04-14
  • 2019-04-06
  • 1970-01-01
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多