使用平面列表在React Native中遇到我的第一个问题
我有一个平面列表如下:
render() {
this.state.loadItems.forEach(function(item, index) {
item.id = index;
});
return (
<FlatList data={this.state.loadItems} extraData={this.state} renderItem={({item}) => this.renderLineItem(item)} keyExtractor={(item, index) => item.id}/>
);
}
renderLineItem(item) {
return <LoadListItem id={item.id} loadItem={item} configChanged={this.configHandler} itemRemoved={this.removeHandler}></LoadListItem>
}
在LoadListItem中我有一个回调,它从状态列表中删除项目,因为有一个弹出窗口来删除LoadListItem,这实现如下:
removeHandler(index) {
var newState = {};
newState.loadItems = this.state.loadItems.slice(0);
newState.loadItems.splice(index,1);
this.setState(newState, this.updateParent);
}
我正在使用ExtraData,使用切片等克隆数组但是在我的生活中,列表无法正确呈现。使用调试器我可以看到在调用set状态后,然后使用新列表调用render和renderLineItem ......但是列表在视觉上删除了错误的项目。例如,如果我有一个包含A,B,C,D和I的列表,则删除CI可以看到状态更新为A,B,D ..我可以使用调试器在渲染方法中验证但渲染可视化显示A,B ,C ..所以删除已经工作...但错误的项目。如果我单击一个不同的选项卡(从视图中删除列表),然后再次打开它自己修复。所以状态正在正确更新...但视图删除了错误的项目......任何想法? 干杯
答案 0 :(得分:5)
这可能是州不变性和/或索引问题。作为一般规则,总是尽量避免直接改变状态(即使用this.state.loadItems.forEach()来设置id)。这是一篇有关该主题的有用文章:https://medium.com/pro-react/a-brief-talk-about-immutability-and-react-s-helpers-70919ab8ae7c
理想情况下,您的数据在创建时已经具有唯一ID,但是当您必须自己添加时,请在启动数据时执行此操作,无论是从api还是在componentDidMount()中,而不是在render()中。
createIdsForData = () => {
// returns a new array with ids from index
let dataWithIds = this.state.loadItems.map((item, index) => {
item.id = index;
});
this.setState({
loadItems: dataWithIds;
});
}
由于索引在删除/添加组件时可能有点变幻无常,我还建议将LoadItem的id传递给removeHandler而不是索引。
removeHandler = (id) => {
// returns new array with item filtered out
this.setState({
loadItems: this.state.loadItems.filter(item => item.id === id);
});
}
希望这会有所帮助,欢呼。