如何在React状态中更新对象

18

我有一个JS对象(不是数组)中的索引列表users,它是React状态的一部分。

{
    1: { id: 1, name: "John" }
    2: { id: 2, name: "Jim" }
    3: { id: 3, name: "James" }
}

如何达到最佳实践:

  1. 使用id(4)作为键添加新用户 { id: 4, name: "Jane" }
  2. 删除id为2的用户
  3. 将用户#2的名称更改为“Peter”

不使用任何不可变的帮助程序。我正在使用Coffeescript和Underscore(所以_.extend可以使用...)。

谢谢。

5个回答

9

以下是我会做的事情

  • 添加: var newUsers = _.extend({}, users, { 4: { id: 4, ... } })
  • 删除: var newUsers = _.extend({}, users) 然后 delete newUsers['2']
  • 更改: var newUsers = _.extend({}, users) 然后 newUsers['2'].name = 'Peter'

1
这是正确的答案。使用“extend”创建一个新对象,然后进行变异。 - Blair Anderson
1
我同意,但在“更改”情况下,我们还必须复制修改后的用户对象,就像这样:var newUser = _.extend({}, users['2'], { name: 'Peter' }); var newUsers = _.extend({}, users, { 2: newUser }); - pierrepinard_2
@pierrepinard_2 不错的观点,这使得 shouldComponentUpdate 对于显示单个用户的组件更好。 - kavun

5
如果您没有使用Flux,您可以使用this.setState()来更新状态对象。
delUser(id) {
    const users = this.state.users;
    delete users[id];
    this.setState(users);
}

addChangeUser(id, name) {
    const users = this.state.users;
    users[id] = {id: id, name: name};
    this.setState(users);
}

然后,您可以使用以下方法执行测试用例:
addChangeUser(4, 'Jane);
addChangeUser(2, 'Peter');
delUser(2);

你的 addUser 方法将会更新对象的键 id,而不是像 OP 指定的那样添加一个键为 4 的对象。changeName 也有同样的问题。 - Jordan Running
你说得对。我想得比打字快了。我已经更新了答案。感谢你指出来。 - Kelly Keller-Heikkila
2
如果您正在使用ES2015(ES6),则可以执行this.setState({ [id]: { ... }); - Jordan Running
1
请注意,这些方法不是不可变的。您正在直接突变this.state。OP似乎希望保持不可变状态,“没有任何不可变的帮助程序”。 - kavun
JavaScript中的对象是按引用传递的,因此您正在此处更改原始对象 @KellyKeller-Heikkila。 - Martin Sojka
1
这些操作会改变状态对象。正确答案是https://dev59.com/11oV5IYBdhLWcg3wIb34#36650760。 - Blair Anderson

2
除了使用 _.extend 外,您还可以使用 Map 存储用户相关信息。请参考 Map
let user = new Map();
user.set(4, { id: 4, name: "Jane" }); //adds with id (4) as key
user.myMap.set(2, { id: 2, name: "Peter" }); // set user #2 to "Peter"
user.delete(3); //deletes user with id 3

1
使用 spreads:
添加
this.setState({
  ...this.state,
  4: { id: 4, name: "Jane" },
}

移除 id 2

let prevState = this.state;
let {"2": id, ...nextState} = prevState;
this.setState({
  ...nextState,
}

修改 id 2

this.setState({
  ...this.state,
  2: {
    ...this.state["2"],
    name: "Peter",
  }
}

0

setState 还接受一个函数,你可能会觉得更加直观

function add( user ) {
  this.setState( users => {
    users[ user.id ] = user
    return users
  }
}

function remove( id ) {
  this.setState( users => {
    delete users[ id ]
    return users
}

这些函数假定您的state对象您的users对象,如果实际上是state.users,那么您需要挑选users,将一个函数传递给setState始终会调用传递实际state对象。
在本例中,add也可用于修改,具体情况取决于您的实际用例,您可能需要创建单独的帮助程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接