简体   繁体   English

数据更新时,React Native Flatlist会多次渲染同一项目

[英]React Native Flatlist renders the same item multiple times when the data updates

The react native flatlist component renders the same item as many times as the data list when the data updates. 当数据更新时,react native平面列表组件渲染同一项目的次数与数据列表的次数相同。 this is for a chat application. 这是聊天应用程序。 when the user clicks the send button, this.state.messages gets updated and causes the flatlist to rerender. 当用户单击“发送”按钮时,this.state.messages会更新,并使平面列表重新呈现。 however, when it rerenders, all the components are rendered the same. 但是,重新渲染时,所有组件都会呈现相同的效果。

Chat.js Chat.js

 import React, { Component } from 'react'; import { View, FlatList } from 'react-native'; import { connect } from 'react-redux'; import { ChatBubble, Input } from './'; import { Header } from '../header'; class Chat extends Component { state={ messages: [], }; componentWillMount() { this.setState({ messages: [ { text: this.props.navigation.state.params.chat.lastMessage, direction: 'left', timeStamp: new Date().getTime(), id: '666', user: { displayName: this.props.navigation.state.params.chat.displayName, }, }, { text: 'Thanks Nick!', timeStamp: new Date().getTime(), direction: 'right', id: '589', user: { displayName: 'You', }, }, ], }); } onSend = (message) => { const messageData = { text: message, timeStamp: new Date().getTime(), direction: 'right', id: Math.random(1000).toString(), user: { displayName: 'You', }, }; if (message !== '') { this.setState({ messages: this.state.messages.concat([messageData]), }); } setTimeout(() => this.list.scrollToEnd(), 200); } renderMessages = ({ item }) => { return <ChatBubble message={item} />; } render() { return ( <View style={{ flex: 1, backgroundColor: 'white' }}> <Header title={this.props.navigation.state.params.chat.displayName} /> <FlatList keyboardShouldPersistTaps='always' data={this.state.messages} contentContainerStyle={{ backgroundColor: 'white', justifyContent: 'flex-end', flexGrow: 1 }} keyExtractor={message => message.id} renderItem={this.renderMessages} ref={(ref) => { this.list = ref; }} /> <Input onPress={this.onSend} /> </View> ); } } const mapStateToProps = (state) => { let user; if (state.user.user) { user = state.user.user; } return { user }; }; export default connect(mapStateToProps)(Chat); 

ChatBubble.js ChatBubble.js

 import React, { Component } from 'react'; import { View, Clipboard, Text, TouchableWithoutFeedback } from 'react-native'; import moment from 'moment'; import { colors } from '../../config'; let message; class ChatBubble extends Component { constructor(props) { super(props); message = this.props.message; } render() { return ( <View style={styles[message.direction].container}> <View style={styles.topContainerStyle}> <Text style={styles[message.direction].infoStyle}> {message.user.displayName} </Text> <Text style={styles[message.direction].infoStyle}> {moment(message.timeStamp).format('LT')} </Text> </View> <Text style={styles[message.direction].message}> {message.text} </Text> </View> ); } } const styles = { left: { container: { borderRadius: 20, borderBottomLeftRadius: 0, marginTop: 8, marginRight: 150, marginLeft: 10, paddingHorizontal: 10, paddingVertical: 5, alignSelf: 'flex-start', backgroundColor: colors.other.chatBubble, }, message: { color: 'black', padding: 10, paddingTop: 5, fontFamily: 'avenir_roman', fontSize: 16, }, infoStyle: { color: 'black', padding: 10, paddingBottom: 0, fontSize: 12, fontFamily: 'avenir_light', }, }, right: { container: { borderRadius: 20, borderBottomRightRadius: 0, marginTop: 8, marginRight: 10, marginLeft: 150, paddingHorizontal: 10, paddingVertical: 5, alignSelf: 'flex-end', backgroundColor: colors.secondary.blue, }, message: { color: 'white', padding: 10, paddingTop: 5, fontFamily: 'avenir_roman', fontSize: 16, }, infoStyle: { color: 'white', padding: 10, paddingBottom: 0, fontSize: 12, fontFamily: 'avenir_light', }, }, topContainerStyle: { flexDirection: 'row', justifyContent: 'space-between', }, }; export { ChatBubble }; 

我应该得到的行为

我目前收到的行为

From the code you mentioned in the question, it seems the problem is the state not holding previous array element while appending new. 从您在问题中提到的代码来看,似乎问题是在追加新元素时状态不保留先前的数组元素。

const messages = [...this.state.messages,messageData] //

considering this.state.messages as array holding supposed data and same with messageData as single element of array. 考虑this.state.messages作为阵列保持supposed data ,并用相同messageData作为阵列的单个元件。

this.setState({ messages:messages  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM