我不认为这是一个错误,更像是我做错了什么但是就在这里。 我正在为我的应用程序构建一个聊天组件,它非常简单,我输入了一些按下发送按钮添加到列表和显示。 几天前我发现,如果我开始输入大而快的消息,我的JS FPS会下降到10,5甚至1,我今天发现了,因为每次我在TextInput中输入内容时都会实现消息的数据/时间显示并运行onChangeText事件并更改“text”的状态,它重新呈现我的FlatList中的所有项目
这是我的代码:
聊天组件:
<FlatList
key={'chat'}
ref={(ref) => {flatlistRef = ref}}
style={styles.flatlist_main}
data={this.state.items}
extraData={this.state}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
onContentSizeChange={(contentWidth, contentHeight) => {
flatlistRef.scrollToEnd({animated: true});
}}
onLayout={() => {flatlistRef.scrollToEnd({animated: true})}}
/>
onChangedText函数
onFooterTextChanged = (text) => {
this.setState({
text: text,
options_expanded: false,
});
};
onSendMessage按钮功能
onSendButtonPressed = () => {
if(this.state.text !== null && this.state.text !== "") {
this.setState({
items: [
...this.state.items,
{
id: moment().valueOf(),
text: this.state.text,
date: moment().valueOf(),
user: {
id: globals.user_id_value,
avatar: globals.user_photo,
}
}
],
text: "",
options_expanded: true,
});
}
};
FlatList的renderItem函数
renderItem = (item) => {
const data = item.item;
const renderAvatar = this.renderAvatar(item);
const renderTime = this.renderTime(item);
if('text' in data){
return(
<ChatTextItem
keyy={data.id}
self={globals.user_id_value === data.user.id}
text={data.text}
user={data.user}
renderAvatar={renderAvatar}
sameUser={!renderAvatar}
renderTime={renderTime}
time={this.getTime(data.date)}
/>
)
} else if('image' in data) {
return(
<ChatImageItem
keyy={data.id}
self={globals.user_id_value === data.user.id}
image={data.image}
renderAvatar={renderAvatar}
sameUser={!renderAvatar}
renderTime={renderTime}
time={this.getTime(data.date)}
/>
)
}
};
构造函数,如果有帮助
constructor(props){
super(props);
this.state = {
isLoading: false,
options_expanded: true,
text: "",
image: "",
items: [],
};
}
我是用户PureComponent btw。
编辑#1:在TextInput中输入疯子后的控制台
它为我输入的28个字母重新呈现了28次,它确实*已经列出的项目数
编辑#2:对JS文件所做的更改
更改FlatList extraData选项
<FlatList
key={'chat'}
ref={(ref) => {flatlistRef = ref}}
style={styles.flatlist_main}
data={this.state.items}
extraData={this.state.refresh}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
onContentSizeChange={(contentWidth, contentHeight) => {
flatlistRef.scrollToEnd({animated: true});
}}
onLayout={() => {flatlistRef.scrollToEnd({animated: true})}}
/>
并更改构造函数以添加刷新状态
constructor(props){
super(props);
this.state = {
isLoading: false,
options_expanded: true,
text: "",
image: "",
items: [],
refresh: false,
};
}
问题仍然存在
编辑:#3终于找到了问题
作品
<FlatList
key={'chat'}
ref={(ref) => {flatlistRef = ref}}
style={styles.flatlist_main}
data={this.state.items}
extraData={this.state.refresh}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
/>
不起作用
<FlatList
key={'chat'}
ref={(ref) => {flatlistRef = ref}}
style={styles.flatlist_main}
data={this.state.items}
extraData={this.state.refresh}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
onContentSizeChange={(contentWidth, contentHeight) => {
flatlistRef.scrollToEnd({animated: true});
}}
onLayout={() => {flatlistRef.scrollToEnd({animated: true})}}
/>
任何想法为什么?请!
如果有人能帮我找到问题的解决方案,我将不胜感激。
答案 0 :(得分:0)
由于您的extraData
收到了整个州
这是一个PureComponent,这意味着它不会重新渲染 道具仍然浅薄相等。确保renderItem的所有内容 函数依赖于作为prop(例如extraData)传递而不是 ===更新后,否则您的UI可能无法更新更新。这包括数据支柱和父组件状态
因此,这是预期的行为,因为每次用户在输入字段中输入时都会更新状态。
此外,FlatList应仅呈现(或重新呈现)屏幕中可见的项目
为了限制内存并启用平滑滚动,内容是 在屏幕外异步渲染。这意味着可以滚动 比填充率快,并暂时看到空白内容。这是一个 权衡可以调整,以满足每个应用程序的需要, 我们正在努力在幕后改进它。
尝试修复extraData
。类似extraData={this.state.refresh}
的内容,当用户按下this.state.refresh
按钮时会更新send
。
此处有更多详情:https://facebook.github.io/react-native/docs/flatlist.html
希望有所帮助
答案 1 :(得分:0)
显然,如果我从onLayout
中移除onContentSizeChanged
和FlatList
个事件,它会停止渲染任何状态更改,并且只有extraData中提供的状态,仍然无法解决我的问题问题,它只会让业绩出乎意料地变得更糟。
感谢所有帮助解决这个问题的人。
答案 2 :(得分:-1)
我不认为这是错误,这就是我们对你的聊天应用程序所需要的。当您更新每个onPress(onSendButtonPressed)的状态以在列表中显示新消息时。所以它重新呈现列表。可能是我的建议,你只需在你的平面列表中显示最近的消息。即flatList中的最后3或4天消息,当用户超过4天后加载更多消息。这有助于您提高聊天应用程序的性能。