在我的React状态下,我有状态:
this.state = {
users: [{
id: 1,
name: "john",
age: 27
}, {
id: 2,
name: "ed",
age: 18
}, {
id: 3,
name: "mel",
age: 20
}]
}
我正确渲染name
。当您单击名称时,它应该删除名称,该名称需要onClick
,该{1}}接收函数并返回removeUser
函数。
我的理解是你不想在React中改变状态,而是返回一个新的状态。所以,在我的removeUser
函数中,我做了:
removeUser(index) {
// Making a new copy of the array
const users = [...this.state.people].splice(index, 1);
this.setState({ users });
}
bind
this.removeUser = this.removeUser.bind(this).
我的方法Expected 1 to be 0
当我测试我的代码时,我正在按预期删除用户。但是,当我针对我朋友写的测试运行我的代码时,我得到了一个失败的测试说:class Group extends Component {
constructor(props) {
super(props);
this.state = {
users: [
{id: 1, name: "john", age: 27},
{id: 2, name: "ed", age: 18},
{id: 3, name: "mel", age: 20}
]
}
this.removeUser = this.removeUser.bind(this);
}
removeUser(index) {
const users = [...this.state.users].splice(index, 1);
this.setState({ users });
}
render() {
const list = this.state.users.map((user, i) => {
return (
<div onClick={() => this.removeUser(i)} key={i}>{user.name}</div>
);
});
return (
<div>
{list}
</div>
);
}
}
那条消息告诉我,我必须以某种方式改变状态,但我不确定如何。我是否正在返回一个新阵列并正确更新状态?有人可以向我解释在这种情况下我应该如何正确更新我的状态?
以下是完整代码:
def genBins(n):
"""
generate all the binary strings with n-length
"""
max_int = '0b' + '1' * n
for i in range(0, int(max_int, 2)+1, 1):
yield str(format(i, 'b').zfill(n))
if __name__ == '__main__':
print(list(genBins(5)))
答案 0 :(得分:2)
autoplot(m.ca.ppc, data = df.ca, label.size = 3, label=TRUE, label.label="community", shape=FALSE, which=1:6, ncol=3)
看起来它应该是从集合中删除一个项目,我认为它在技术上是。问题是const users = [...this.state.users].splice(index, 1)
不包含您要保留的用户列表。
相反,users
已就地修改了新数组,然后返回已删除的项目:
返回值
包含已删除元素的数组。如果仅删除一个元素,则返回一个元素的数组。如果没有删除任何元素,则返回一个空数组。
相反,如果您想使用splice
,请创建一个新数组:
splice
和然后拼接新数组:
const users = [...this.state.users]
如果您需要sort
数组,则会遇到类似的问题。
react通常不赞成就地修改数据的问题,赞成不可变引用。这是因为React使用大量对象的直接比较作为启发式方法来加快速度。如果您的函数修改了现有的对象实例,React将假定对象没有更改。
复制到新对象和然后对数据进行操作的行为需要进行一些权衡。对于删除单个项目,它可以忽略不计。要删除许多项目,您可以通过其他方法提供更好的服务,例如多个切片调用:
users.splice(index, 1)
然而,这也很冗长。
另一种方法是使用拼接的不可变变体:
const users = [
...this.state.users.slice(0, index)
...this.state.users.slice(index + 1)
]
答案 1 :(得分:2)
您也可以更改onClick并将user.id
而不是索引传递给它。这将允许您过滤结果而不需要拼接数组。
onClick={() => this.removeUser(user.id)}
removeUser(id) {
const users = this.state.users.filter((user) => user.id !== id);
this.setState({ users });
}
答案 2 :(得分:0)
您应该使用slice()
而不是splice()
,因为splice()
会改变原始数组,但slice()
会返回一个新数组。 Slice()
是一个纯函数。纯净更好!!
removeUser(index) {
const users = [
...this.state.users.slice(0, index),
...this.state.users.slice(index+1)
];
this.setState({ users });
}