Почему мой this.setState не обновляет массив

я что-то упускаю? Я использую стиль es6 для добавления в пустой массив в this.state, но ничего не переводится в состояние.

Я должен получить два внутри массива, но после console.infoging ничего не отображается. и мой экран не перерисовывается, поскольку coponentDidUpdate не запущен.

class HomeModal extends Component {
  constructor(props) {
    super(props);
    this.state = {
      specificList: []
    };
    this.updateState = this.updateState.bind(this);
  }

  componentWillMount() {
    this.updateState();
  }

  componentDidUpdate() {
    console.info("after update: ", this.state.specificList);
  }

  updateState = () => {
    this.props.completeList.forEach(index => {
      index.list.forEach(innerArr => {
        if (innerArr.muscleGroup === this.props.selectedBodyPart) {
          console.info("test: ", innerArr);
          this.setState({
            specificList: [...this.state.specificList, innerArr.title]
          });
        }
      });
      console.info("after each loop: ", this.state.specificList);
    });
  };

// console.info results
06:22:48: test:  Object {
06:22:48:   "muscleGroup": "Chest",
06:22:48:   "title": "Barbell Bench Press",
06:22:48: }
06:22:48: after each loop:  Array []
06:22:48: test:  Object {
06:22:48:   "muscleGroup": "Chest",
06:22:48:   "title": "Barbell Bench Press",
06:22:48: }
06:22:48: after each loop:  Array []
06:22:48: after each loop:  Array []

6:08:04: Object { // what innerArr the object looks like
06:08:04:   "muscleGroup": "Chest",
06:08:04:   "title": "Barbell Bench Press",
06:08:04: }
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
70
4

Ответы 4

Попробуйте записать вывод с помощью обратного вызова setState, например:

this.setState({
    specificList: [...this.state.specificList, innerArr.title]
}, () => {
    console.info("after each loop: ", this.state.specificList);
});

Небольшие заметки о .setState() от документы:

React may batch multiple setState() calls into a single update for performance.

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

Я бы просто использовал другой объект в начале цикла (копирование из текущего состояния), изменил бы эту переменную в цикле, а затем сделал бы один .setState() в самом конце, после того, как все ваши циклы будут выполнены.

setState - это асинхронный. Это означает, что значение значений состояния не обновляется сразу.

Вы просматриваете серию значений и устанавливаете состояние specificList на конкатенацию текущего значения specificList плюс один элемент из массива.

Итак, если бы specificList был ['a', 'b', 'c'], а массив, который вы перебираете, был [1, 2, 3], то вы бы по существу вызывали:

setState({ specificList: ['a', 'b', 'c', 1] })
setState({ specificList: ['a', 'b', 'c', 2] })
setState({ specificList: ['a', 'b', 'c', 3] })

Вы можете увидеть, как все значения массива, кроме последнего, не учитываются.

Один из способов исправить это - передать функцию setState вместо значения. Это позволит вам работать с асинхронным поведением setState:

updateState = () => {
    this.props.completeList.forEach(index => {
        index.list.forEach(innerArr => {
            if (innerArr.muscleGroup === this.props.selectedBodyPart) {
                console.info("test: ", innerArr);
                this.setState(({ specificList } => ({
                  specificList: [...specificList, innerArr.title]
                }));
            }
        });
      });
};

Лучше всего вызвать setState после того, как вы пройдете оба цикла. Например, вы можете сделать что-то вроде этого:

updateState = () => {
  let temp = this.state.specificList;

  this.props.completeList.forEach(index => {
    index.list.forEach(innerArr => {
      if (innerArr.muscleGroup === this.props.selectedBodyPart) {
        console.info("test: ", innerArr);
        temp.push(innerArr.title);
      }
    });
    console.info("after each loop: ", temp)
  });

  this.setState({ specificList: temp }); 
}

Другие вопросы по теме