数组中对象属性的SetState

时间:2019-07-11 14:27:25

标签: arrays reactjs object state

在我的状态下,我想更新对象数组中第一项的对象属性。即使我正在采取措施确保不可变性,对象属性也不会改变。

this.state = { 
    myFruits: [{a: false, b: 2, c: 'apple'}, {'a': false, b: 4, c: 'kiwi'}, ...],
    otherCategory: {} 
}

/// further down the code in componentDidUpdate

{ myFruits } = this.state;

let copyFruits = [...myFruits];
let newFruit = { ...copyFruits[0], a : true };
// console.log(newFruit): {a: true, b: 2, c: 'apple'}
copyFruits[0] = newFruit;
// console.log(copyFruits[0)] = {a: true, b: 2, c: 'apple'}
this.setState({ myFruits: copyFruits  });

// the end result is the same as the original state, where the first item, apple, has a : false instead of expected a : true

此更改是在componentDidUpdate中进行的,我不确定这是否有效果。

2 个答案:

答案 0 :(得分:0)

我想问题是您的componetDidUpdate方法没有被调用。 您在此处编写的代码非常好。

class SolutionExample extends React.Component {
constructor(){
    super()
    this.state = { 
myFruits: [{a: false, b: 2, c: 'apple'}, {'a': true, b: 4, c: 'kiwi'}],
otherCategory: {} 
}
}
changeKey =() =>{
    let { myFruits } = this.state;
    let copyFruits = [...myFruits]
    let newFruit = { ...copyFruits[0], a : true };

copyFruits[0] = newFruit;
this.setState({ myFruits: copyFruits  });
}
componentDidUpdate()
    {
        // this method is called whenever the state is changed  }
render() {
    let { myFruits  }  = this.state;
    return (
        <div>

            <h1>Solution</h1>
            {myFruits.map((item) =>{
                if(item.a){
                    return(<h2>{item.b + '-' + item.c}</h2>)
                }   
            })}
            <button onClick={this.changeKey}>Change state</button>
        </div>
    );
}
}

ReactDOM.render(<SolutionExample />, document.getElementById('example')); 

这里是链接:https://codepen.io/anon/pen/pXYdWQ

答案 1 :(得分:-2)

您可以将更改简化为:

const { myFruits } = this.state;

let newFruit = { ...myFruits[0], a : true };

this.setState({ myFruits: [newFruit, ...myFruits.splice(1)]  });

此外,更好的方法是通过ID或任何唯一标识符map并更新所需的对象。

this.setState({
 myFruits: myFruits.map(fruit => {
   if(fruit.c === "apple") {
     fruit.a = true
     return fruit;
   }

   return fruit;
 })
})