我遇到了listview的问题而没有刷新它的数据源,除非我离开页面然后回来。我的listview在NavigatorIOS组件中。
每个帖子我都读过sais用新对象刷新数据源。当我从数据源中删除/添加内容时,它工作正常,但是当我只想从数据源编辑一行时,它不会刷新视图。
此代码不起作用
editMessage(title, message, messageIndex, replyIndex){
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var newData = [];
newData = this.state.data.slice();
newData[messageIndex].replies[replyIndex].title= title;
newData[messageIndex].replies[replyIndex].message= message;
this.setState({data: newData});
this.setState({dataSource: ds.cloneWithRows(newData)});
},
然而像这样的样本工作正常
removeMessage(index){
console.log(index);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var newData = this.state.data;
newData.splice(index, 1);
this.setState({dataSource: ds.cloneWithRows(newData)});
},
编辑:我已经尝试过按值复制,但它仍无效。
newData = JSON.parse(JSON.stringify(this.state.data));
newData[messageIndex].replies[replyIndex].title= title;
newData[messageIndex].replies[replyIndex].message= message;
this.setState({dataSource: ds.cloneWithRows(newData)});
this.setState({data: newData});
答案 0 :(得分:0)
我想知道它是否是this.state上的引用错误..因为您正在更改对象数组中的对象的属性,这些对象将指针返回到原始this.state数组。如果你然后将该数组设置为原始状态,它会认为它是相同的数组,因为您只修改数组中的对象。来自array.slice上的Mozilla文档
"对于对象引用(而不是实际对象),slice将对象引用复制到新数组中。原始数组和新数组都引用相同的对象。如果引用的对象发生更改,则更改对新的和原始数组都可见。" https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
答案 1 :(得分:0)
我认为问题出在我的逻辑中,即使状态更新,孩子也不会刷新。
目前,父数据源看起来像这样
[
{
index:
author:
title:
message:
replies: [{
author:
title:
message:
}]
}
]
子组件仅使用replies数组作为数据源
replies: [{
author:
title:
message:
}]
为什么这很重要?当我更改父状态时,子数据源也会更改,因为它使用相同的数据源。但它不刷新页面。我必须更新childs数据源,即使父级已更改状态。
父母有这段代码
editMessage(title, message, messageIndex, replyIndex){
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state.data[messageIndex].replies[replyIndex].title= title;
this.state.data[messageIndex].replies[replyIndex].message= message;
this.setState({dataSource: ds.cloneWithRows(this.state.data)});
this.setState({data: this.state.data});
},
并且孩子有这个代码
editMessage(title, message, replyIndex){
this.props.editMessage(title, message, this.props.pushEvent.index ,replyIndex);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({dataSource: ds.cloneWithRows(this.state.replies)});
},