繁体   English   中英

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

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

当数据更新时,react native平面列表组件渲染同一项目的次数与数据列表的次数相同。 这是聊天应用程序。 当用户单击“发送”按钮时,this.state.messages会更新,并使平面列表重新呈现。 但是,重新渲染时,所有组件都会呈现相同的效果。

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

 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 }; 

我应该得到的行为

我目前收到的行为

从您在问题中提到的代码来看,似乎问题是在追加新元素时状态不保留先前的数组元素。

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

考虑this.state.messages作为阵列保持supposed data ,并用相同messageData作为阵列的单个元件。

this.setState({ messages:messages  });

暂无
暂无

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

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