javascript - React Native Flatlist 在数据更新时多次渲染同一个项目
问题描述
当数据更新时,react native flatlist 组件渲染同一个项目的次数与数据列表一样多。这是一个聊天应用程序。当用户单击发送按钮时, this.state.messages 会更新并导致平面列表重新呈现。但是,当它重新渲染时,所有组件都以相同的方式渲染。
聊天.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 });
推荐阅读
- ios - Fastlane iOS 测试在本地通过,但不是来自 Jenkins
- c# - 为什么 Lambda 表达式会返回 System.Linq.Enumerable+WhereSelectEnumerableIterator`2 作为结果
- android - addValueEventlistener 没有编译,编译器直接进入下一步
- javascript - Angular - 类型的参数不可分配给参数
- acumatica - 如何在销售订单中获取机会关系
- apache-flink - 为 Flink SQL 添加单元测试
- performance - 如何找到消耗高 CPU 和内存的 Jenkins 构建作业
- azure-application-insights - Azure 应用程序洞察力查询合并行
- c# - asp.net mvc(迁移)
- csv - 如何在 Paraview 中查看所有时间步长的总和/平均速度?