реагировать массив массивов объекта с помощью карты не работает - PullRequest
0 голосов
/ 21 сентября 2018

У меня проблема с изменением значения setState вложенного массива объекта.Ниже в коде предполагается изменить вопрос с идентификатором 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 голосов
/ 21 сентября 2018

Я думаю, это потому, что 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]) // did not see id of 2 being changed to true?
)
0 голосов
/ 21 сентября 2018

Строка 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]);
});
0 голосов
/ 21 сентября 2018

Вы не вызываете свой 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 );
    ....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...