如何使用state更新React js中的对象数组

问题描述 投票:0回答:2

我想只更新一个对象的值,但更新一个对象的值,更新所有对象的值。

let default = {
    name: '',
    age: ''
}
this.state = {
    values: Array(2).fill(default)
}

updateName (event) {
    let index = event.target.id,
    values = this.state.values;

    values[index].name = event.target.value;

    this.setState ({
        values: values
    });
}
javascript arrays reactjs object
2个回答
1
投票

该代码中存在四个重要问题。

  1. 您对阵列中的所有条目使用相同的对象。如果要使用不同的对象,则必须创建默认的多个副本。
  2. 你错误地打电话给setState。无论何时基于现有状态设置状态(并且您在values上间接设置this.state.values),都必须使用setState的函数回调版本。更多:State Updates May Be Asynchronous
  3. 你不能直接修改this.state.values中持有的对象;相反,您必须复制该对象并进行修改。更多:Do Not Modify State Directly
  4. default是一个keyword(即使它目前没有使用),你不能用它作为标识符。让我们用defaultValue代替。

以下是解决这三种问题的一种方法(见评论):

// #4 - `default` is a keyword
let defaultValue = {
    name: '',
    age: ''
};
this.state = {
    // #1 - copy default, don't use it directly
    values: [
        Object.assign({}, defaultValue),
        Object.assign({}, defaultValue)
    ] // <=== Side note - no ; here!
}

updateName (event) {
    let index = event.target.id,
    // #2 - state updates working from current state MUST use
    // the function callback version of setState
    this.setState(prevState => {
        // #3 - don't modify state directly - copy the array...
        values = prevState.values.slice();

        // ...and the object, doing the update
        values[index] = {...values[index], name: event.target.value};

        return {values};
    });
}

注意上面的这一行:

values[index] = {...values[index], name: event.target.value};

...使用来自this JavaScript enhancement proposal的语法,目前处于第4阶段(它将在ES2018快照规范中)并且通常在React构建环境中启用。


0
投票

我会使用Array.prototype.map函数与object spread syntax (stage 4)的组合:

请注意,我将default对象的名称更改为objdefault是一个reserved key word in javascript

let obj = {
    name: '',
    age: ''
}
this.state = {
    values: Array(2).fill(obj)
}

updateName(event){
    const {id, value} = event.target;  
    this.setState(prev => {
    const {values} = prev;

    const nextState = values.map((o,idx) => {
        if(idx !== id)
        return o; // not our object, return as is

      return{
          ...o,
          name: value;
        }
    });

      return{
        values: nextState
      }
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.