使用地图反应对象的setState数组不起作用?

时间:2018-09-21 00:49:57

标签: javascript reactjs ecmascript-6

我在执行setState更改对象嵌套数组的值时遇到问题。下面的代码假设 更改ID 2的问题以回答:正确,但事实并非如此,这是怎么回事?

this.state = {
  questions: [
    {
      id: 1,
      answer: ''
    },
    {
      id: 2,
      answer: ''
    },
  ]
}
//I have a click event somewhere
this.setState(
  {
    questions: this.state.questions.map(q => {
      if (q.id === 2) {
        return {
          ...q,
          answer: true
        }
      } else {
        return { ...q }
      }
    })
  },
  console.log(this.state.questions[1]) // did not see id of 2 being changed to true?
)

3 个答案:

答案 0 :(得分:2)

在执行console.log(this.state.questions[1])行之前先执行this.setState行,这就是将旧状态打印到控制台的原因。您应该将行放在函数内部以延迟执行:

this.setState(..., () => console.log(this.state.questions[1]));

如果更改后的状态是从当前状态派生的,还建议使用函数作为第一个参数,因为React不会立即应用新状态,因此this.state可能会在React应用新状态时过时:

this.setState(state => ({
  questions: state.questions.map(q => {
    if (q.id === 2) {
      return {...q, answer: true};
    }
    return q;
  })
}), () => {
  console.log(this.state.questions[1]);
});

答案 1 :(得分:0)

您没有调用setState回调。尝试这样:

this.setState(
  {
    questions: this.state.questions.map(q => {
      if (q.id === 2) {
        return {
          ...q,
          answer: true
        };
      }
      return { ...q };
    })
  },
  () => console.log(this.state.questions[1]) // did not see id of 2 being changed to true?
);

但是,由于您正在使用当前状态来再次更新您的状态,因此最好使用功能性setState。

this.setState(
  currentState => ({
    questions: currentState.questions.map(q => {
      if (q.id === 2) {
        return {
          ...q,
          answer: true
        };
      }
      return { ...q };
    })
  }),
  () => console.log(this.state.questions[1])
);

此外,您不必将状态记录在setState的回调中。您可以在render方法中记录状态,而不会遇到setState的回调问题。

this.setState(
  currentState => ({
    questions: currentState.questions.map(q => {
      if (q.id === 2) {
        return {
          ...q,
          answer: true
        };
      }
      return { ...q };
    })
  })
);

....

render() {
    console.log( this.state );
    ....
}

答案 2 :(得分:-1)

我认为这是因为Array.map返回一个数组。试试:

this.setState(
{
questions: this.state.questions.map(q => {
  if (q.id === 2) {
    q.answer = true;
  } 
  return q;
})

},   console.log(this.state.questions [1])//没看到2的ID更改为true吗? )