React Native FlatList一次渲染一些项目

时间:2018-08-21 11:13:20

标签: react-native

我的应用程序中有一个聊天消息列表,新项添加到了聊天消息列表的底部。我使用了另一个SO问题中的一些代码,以在添加新项目时使FlatList固定在底部,如下所示

<FlatList
    data={messages}
    renderItem={({item}) => <ChatMessage message={item}></ChatMessage>}
    keyExtractor={(item, index) => index.toString()}
    initialNumToRender={messages.length}
    initialScrollIndex={messages.length-1}
    ref={ref => this.flatList = ref}
    onContentSizeChange={(contentWidth, contentHeight)=>{        
        this.flatList.scrollToEnd();
    }}

/>

问题在于,当初始列表呈现时(现在只有35个条目,目前已硬编码在数组中),似乎仅呈现了几个条目,然后向下滚动,然后呈现更多,然后向下滚动直到最终完成渲染并坚持到底。尽管添加了initialNumToRender = {messages.length}并为每个结果渲染了一个非常简单的节点,但是它又不稳定又慢。

理想情况下,我想在向用户显示任何内容之前我需要等待它完全呈现,但是(A)他们必须等待几秒钟才能开始使用聊天室,并且(B)我不认为这就是Flatlist的工作方式,我认为元素在呈现之前必须是可见的。

有没有更好的方法可以做到这一点? (顺便在Android上进行测试)

编辑:添加ChatMessage组件以提高完整性

// Chat Message
import React, { Component } from 'react'

import { 
    StyleSheet,
    ImageBackground,
    Text,
    View
} from 'react-native'

class ChatMessage extends Component {

    constructor(props) {
        super(props)
        this.state = {  }
    }

    render() { 
        return (
            <View style={styles.chatMessage}>

                <View style={styles.chatMessage_layout}>

                    <View style={styles.chatMessage_pic}>
                        <View style={styles.chatMessage_pic_image}>
                            <ImageBackground 
                                source={require('./assets/images/profile-pics/example-profilr.png')} 
                                style={styles.chatMessage_pic_image_background}
                                imageStyle={{ borderRadius: 40/2 }}
                                resizeMode="cover"
                            >
                            </ImageBackground>
                        </View>
                    </View>
                    <View style={styles.chatMessage_details}>
                        <View style={styles.chatMessage_name}>
                            <Text style={styles.chatMessage_name_text}>
                                {this.props.message.name}
                                <Text style={styles.chatMessage_name_time}>  24h</Text>
                            </Text>
                        </View>
                        <View style={styles.chatMessage_message}>
                            <Text style={styles.chatMessage_message_text}>{this.props.message.text}</Text>
                        </View>
                    </View>

                </View>

            </View>
        )
    }
}

export default ChatMessage;


const styles = StyleSheet.create({

    chatMessage: {
        paddingVertical: 10,
        paddingHorizontal: 24
    },

    chatMessage_layout: {
        flexDirection: 'row'
    },

    chatMessage_pic: {
        width: 40,
        height: 40,
        marginRight: 12
    },

    chatMessage_pic_image: {
        width: 40,
        height: 40
    },

    chatMessage_pic_image_background: {
        width: 40,
        height: 40
    },

    chatMessage_details: {
        flex: 1
    },

    chatMessage_name_text: {
        color: '#FFF',
        fontSize: 14,
        fontWeight: 'bold'
    },

    chatMessage_name_time: {
        fontSize: 11,
        color: 'rgba(255,255,255,0.6)'
    },

    chatMessage_message: {
        flexDirection: 'row',
        alignItems: 'center'
    },

    chatMessage_message_text: {
        color: '#FFF',
        fontSize: 12
    }

})

1 个答案:

答案 0 :(得分:3)

如果您的项目数量少于 ,并且要一次渲染所有项目,则应使用ScrollView中所述的docs

ScrollView :一次渲染所有元素,但是如果有大量元素,则渲染速度慢。

FlatList :在即将出现时以惰性模式渲染项目,并在可见时将其删除显示以节省内存,使其可用于大型列表。

对于平面列表优化,您需要在渲染子对象时使用PureComponent,以便仅shallow compares the props

keyExtractor中也为您的item使用唯一ID ,并且不依赖于index,因为当项目更新{{1 }}不可靠,并且可能会改变