尝试通过映射字符串列表来更新创建的有状态组件列表时遇到问题。当我通过切割数组以通过其索引删除元素来删除其中一个组件时,问题就出现了。
每个组件都有自己的状态,即从API获取。问题是,当我删除数组的元素时,下一个组件的状态与我删除组件的状态重叠。
我的代码与此类似:
class MyDashboard extends React.Component {
constructor(props){
super(props);
this.state = {
activeItems: [0,1,2,3],
}
this.removeItem = this.removeItem.bind(this);
}
removeItem(indx){
let tempItems= this.state.activeItems;
tempItems.splice(indx,1);
this.setState({activeItems:tempItems});
}
render(){
let conditionalDash;
let conditionalComponent;
let temporalArray = this.state.activeEntries.map((entry , i) => {
return (<MyDash key={i} index {i}/> removeItem={this.removeItem});
});
render(){
return (
<div id='dashContainer'>
{temporalArray}
</div>
)
}
}
在我的MyDashComponent中我有这样的东西:
class MyDash extends React.Component{
constructor(props){
super(props);
this.state={
fetchedData:null,
}
}
componentDidMount(){
API.fetchData(this.props.index).then(response => {
this.setState({fetchData:response.data})
)
}
render(){
return(
<div> {this.props.index} {this.state.fetchedData}</div>
)
}
}
有什么东西我不见了吗?
我得到的行为是当i删除this.state.activeItems [2]时,该元素的状态与前一个组件相同。我期待元素[2]的状态与具有元素[3]的状态相同。
编辑: 我忘记告诉的一点是,MyDash组件的道具是正确的,只是不属于组件的状态,它来自已删除的组件。
感谢阅读,我希望有人可以帮助我。
答案 0 :(得分:0)
谁混合了这种行为或slice
和splice
slice
会返回一个新数组,而splice
会修改现有数组
根据MDN文档:
splice:
splice()
方法更改数组的内容 删除现有元素和/或添加新元素。语法:array.splice(start,deleteCount)
slice:
slice()
方法返回一部分的浅表副本 数组到从头到尾选择的新数组对象(结束时不是 包括在内)。原始数组不会被修改。语法:
arr.slice() arr.slice(begin) arr.slice(begin, end)
您可以将代码更改为
removeItem(indx){
let tempItems= this.state.activeItems;
tempItems.splice(indx,1);
this.setState({ activeItems:tempItems });
}
此外,您不应该直接改变状态,您应该创建状态数组的副本,然后更新它。
removeItem(indx){
let tempItems= [...this.state.activeItems]; // this is do a shallow copy, you could use something else depending on your usecase
tempItems.splice(indx,1);
this.setState({ activeItems:tempItems });
}
答案 1 :(得分:0)
您还可以使用Array.prototype.filter删除该项目:
removeItem(indx) {
this.setState({
activeItems: this.state.activeItems.filter((_, index) => index !== idx),
})
}
或
removeItem(indx) {
this.setState(prevState => ({
activeItems: prevState.activeItems.filter((_, index) => index !== idx),
}))
}
答案 2 :(得分:0)
我发现错误是我正在使用的列表的键,它是map方法的索引,我读到它必须是一个唯一的键。幸运的是,这修复了渲染动作,状态不再重叠。