我无法在State中更改数组

时间:2019-06-18 08:51:53

标签: javascript arrays reactjs

我无法在此处正确传递代码。所以我将用图片来解释这个问题。 注意:它们都在同一组件中)

问题: 我有一个状态值:

  state = {
    base: [ {tomato: false}, {egg: true} ],
    contents: [
      {mushroom: false},
      {olive: false},
      {greenPepper: false},
      {sausage: false},
      {tomato: false},
      {redPapper: false}
    ],
    selectBase: "tomato"
  };

共有六个按钮。每个按钮都等于“ contents”数组中的一个值。通过这种方式:


<label>
    <Checkbox checked={this.state.contents.olive} onChange= 
      {this.handleChanges('olive')} color="default" value="olive"/>Olive
</label>
// There are 5 more similar buttons.

当我按下按钮时,此功能有效:


  handleChanges = name => event => {
    this.setState({ 
      ...this.state,
      contents: [
        ...this.state.contents,
        {[name]: event.target.checked}
      ]
       });
      console.log(this.state)
  };

当我按下按钮时,我希望更改数组中达到的值。但是相反,它再次向数组添加了相同的值。


enter image description here


我的目标只是更改数组中达到的值。除此之外,它们都需要保持不变。我该怎么办?


对于所有代码: https://codepen.io/guldus/pen/MMeZqO?editors=1010

5 个答案:

答案 0 :(得分:3)

原因是您在handleChanges

中添加了一个新对象
handleChanges = name => event => {
  this.setState({
    ...this.state,
    contents: [
      ...this.state.contents,
      {[name]: event.target.checked} <-- Here you add a new object to the contents array 
    ]
  })
}

您需要做的是在数组中找到元素并更新

handleChanges = name => event => {
  this.setState(prevState => ({
    // here we check if the current obj that we iterate on has the name field in it
    // if it does we replace it with a new object with the name
    // as the key and the new checked value
    contents: prevState.contents
      .map(obj => name in obj ? {[name]: event.target.checked} : obj)
  }))
}

答案 1 :(得分:1)

setState之后您看不到状态已更改,因为setState是异步方法,如果您想查看setState的结果,则需要使用回调:

setState(
  { field: "someValue" },
  () => console.log(this.state)
);

https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296

答案 2 :(得分:1)

您应该找到一个对象,然后更改其值。

handleChanges = name => event => {
   this.setState({
      ...this.state,
      contents: [
         ...this.state.contents,
         {  } // like a pushing new object. This is a problem
      ]
   });
}

答案 3 :(得分:1)

将索引作为第二个参数传递给函数。

handleChanges = (name, index) => {

  this.setState((prevState) => ({
    contents: [
      ...prevState.contents.slice(0, index),
      Object.assign({}, prevState.contents[index], { [name] : !prevState.contents[name]},
        ...prevState.contents.slice(index + 1))
    ]
  }));
}

并像使用它

const checkboxes = this.state.contents.map((checkbox, index) => (
  <label>
    <Checkbox key={index} checked={this.state.contents[checkbox]} onChange=
      {() => this.handleChanges(checkbox, index)} color="default" value={checkbox} />{checkbox}
  </label>
))

答案 4 :(得分:1)

  1. 如果要在更新中访问状态,最好使用状态更新功能

    this.setState((state, props) => ({
        counter: state.counter + props.increment
    }));
    
    1. 您需要更新确切的值,因此更新的外观如下:

      contents: ...state.contents.map(content => {
      
          if (content.hasOwnProperty(name) {
              return {[name]: event.target.checked}
          }
          return content;
      });