[英]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.