我不认为这是一个错误,更像是我做错了什么但是它就这样了 . 我正在为我的应用程序构建一个聊天组件,它非常简单,我输入了一些按下发送按钮添加到列表和显示 . 几天前,我发现,如果我开始输入大而快的消息,我的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终于找到了问题
Works
<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}
/>
Doesn't Work
<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})}}
/>
任何想法为什么?请!
如果有人能帮助我找到解决问题的方法,我将不胜感激 .
3 回答
我认为这不是bug,这正是我们对你的聊天应用程序所需要的 . 当您更新每个onPress(onSendButtonPressed)的状态以在列表中显示新消息时 . 所以它重新呈现列表 . 可能是我的建议,你只需在你的平面列表中显示最近的消息 . 即flatList中的最后3或4天消息,当用户超过4天时加载更多消息 . 这有助于您提高聊天应用程序的性能 .
显然,如果我从
FlatList
删除了onLayout
和onContentSizeChanged
事件,它会停止渲染任何状态更改,只有extraData中提供的状态,仍然无法解决我的问题,只会让性能更糟糕 . 感谢所有帮助解决这个问题的人 .看起来这是因为你的
extraData
收到整个州因此,这是预期的行为,因为每次用户在输入字段中键入时都会更新状态 .
此外,FlatList应仅呈现(或重新呈现)屏幕中可见的项目
尝试修复
extraData
. 像extraData={this.state.refresh}
之类的东西,当用户按下send
按钮时this.state.refresh
会被更新 .更多细节:https://facebook.github.io/react-native/docs/flatlist.html
希望能帮助到你