综述
数组的复制,其实在OC
中也有,或者说每种语言应该都有涉及。概念上叫做深拷贝
和浅拷贝
没有什么特别新鲜的点,只是很容易出错。
这里举一个实例来说明容易出错的应用场景
实例
我们通常使用Flatlist
的时候,会将数据源 dataSource
的数组放在state
中去,便于在下拉刷新,上拉加载的时候,通过setState
修改这个state
中的数据,达到刷新页面的效果。
// 上面省略
constructor(props) {
super(props);
this.state = {
dataSource: [],
};
}
当我们通过点击或下拉刷新修改了里头的数据时,就需要用到以下的场景:
错误一:
// 下拉刷新请求道了新的数据
_updateUI = (newDataArray) => {
let tempArray = this.state.dataSource;
tempArray.push(...newDataArray);
this.setState(dataSource:tempArray);
}
这样写是无法激活重新 render
的。因为let tempArray = this.state.dataSource;
拷贝的只是指针,当你做 push 的时候,已经改变了this.state.dataSource
的值,再去setState
,在 pureComponent
中,比对数据后觉得你没有改变什么,不会触发刷新的。
正确的做法:
let tempArray = [...this.state.dataSource];
错误二:
点击//后修改了某个数据,希望触发局部的刷新
_updateUI = (newData, index) => {
let tempArray = [...this.state.dataSource];
tempArray[index] = newData;
this.setState(dataSource:tempArray);
}
看似是已经将数组复制出来了,但是去打断点会发现,tempArray[index] = newData;
这句执行后,this.state.dataSource
里头对应的那个 index 的值又改动了。
道理其实很简单,数组的指针虽然不同了,但是里头元素的指针还是和原先的一样。拷贝还不够深入
正确的做法:
_updateUI = (newData, index) => {
let tempArray = [...this.state.dataSource];
tempArray[index] = {...this.state.dataSource[index],newData};
this.setState(dataSource:tempArray);
}
tempArray[index] = {...this.state.dataSource[index],newData};
, 等号右边用到了解构赋值。newData
会将 展开的...this.state.dataSource[index]
中搜索对应的值,并替换掉。
网友评论