Установка состояния с массивом в React

Я пытаюсь заменить изначально пустой массив массивом, созданным функцией, использующей setState в React. У меня в конструкторе следующее:

this.state = {
    sources: []
};

Это отображает правильный массив (я тестировал его с [0,1,2]). Однако, когда я пытаюсь установитьState в таком методе:

this.setState({
    sources: [0,1,2]
})

он не работает и по-прежнему отображает пустой (или исходный) массив. Я понимаю, что вы не можете изменить массив как состояние непосредственно в React, но я не думаю, что я здесь делаю это. Вот еще несколько вещей, которые я пробовал при исследовании этого вопроса, но ни один из них не помог:

this.setState({
    sources: [...this.state.sources, 1]
})

...

this.setState({
    sources: this.state.sources.concat('test')
})

...

var temp = [0,1,2]
this.setState({
    sources: temp
})

Заранее благодарю за любую помощь!

РЕДАКТИРОВАТЬ Полный код:

export class SrcMenu extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            sources: [],
        };

        this.searchSources = this.searchSources.bind(this);
    }

    searchSources() {
    // commented out the actual method to replace with test code
        var temp=[0,1,2];
        console.info(temp); // [0,1,2] so I know the method works
        this.setState({
            sources: temp // etc for the other things i tried
        })
        console.info("this.state.sources: " + this.state.sources); // empty
    }

    render() {
        return(
        // etc...
          <button type = "button" onClick = {this.searchSources}>Test</button>
        );
    }
}

здесь работает - codeandbox.io/s/l7j005yknz

Paul Fitzgerald 17.07.2018 16:15

В конструкторе должен быть не this.state({ sources: [] };, а this.state = { sources: [] };

Tholle 17.07.2018 16:17

Не могли бы вы опубликовать фрагмент метода, из которого вы вызываете setState

Sebastiaan van Arkens 17.07.2018 16:21

@Tholle, спасибо, это была опечатка в моем вопросе, в фактическом файле кода я написал правильно

Leo T 17.07.2018 16:21

Хорошо. Не могли бы вы включить весь свой компонент с таким поведением? Трудно сказать, что может быть не так в коде, который сейчас обсуждается в вашем вопросе.

Tholle 17.07.2018 16:22

вы уверены, что вызываете этот метод? где этот метод? как ты это называешь? когда вы проверяете, изменился ли state?

Mihai T 17.07.2018 16:23

отредактирован, чтобы включить полный тестовый код

Leo T 17.07.2018 16:31

Вы пытаетесь получить к нему доступ сразу после установки состояния, это не работает. setState асинхронный.

Rikin 17.07.2018 16:33

@Rikin вау, спасибо, я понятия не имел. просто попытался вызвать извне метода, и он отлично сработал. Спасибо!!!!!!

Leo T 17.07.2018 16:35

именно поэтому я спросил when are you checking to see if state has changed. setState является асинхронным, поэтому, если вы проверите его сразу после этого, вы не увидите разницы, хотя изменения в состоянии были сделаны, подробнее здесь асинхронный setState

Mihai T 17.07.2018 16:36
Поведение ключевого слова "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) для оценки ваших знаний,...
1
11
96
2

Ответы 2

Вот пример, который должен работать так, как вы описываете:

class ArrayTest extends React.Component {

  constructor() {
    super();
    this.state = {
      sources: [],
    };
  }

  public render() {

    return (
      <div>
      <div>test: {this.state.sources}</div>
      <button onClick = {this._changeValue}>test</button>
       </div>
    );
  }

  private _changeValue = () => this.setState( {sources: [1,5] } );  
}

ReactDOM.render( 
  <ArrayTest />,
  document.getElementById('content')
);

Есть ли в классах JS public или private?

Rikin 17.07.2018 16:37

Ваш код работает, но вы не учитываете, что setState асинхронный. Если вы зарегистрируете this.state в обратном вызове, который можно указать в качестве второго аргумента для setState, он будет гарантировать, что он обновился.

this.setState({ sources: temp }, () => {
  console.info(this.state.sources);
});

Мы почти каждый день сталкиваемся с одним и тем же вопросом. Почему люди не используют метод рендеринга для регистрации состояния? Я воздерживаюсь от ответа "Использовать метод рендеринга" вместо этого обратного вызова :)

devserkan 17.07.2018 16:39

@devserkan Я сам попался на это, когда начал использовать React. Я думаю, что сейчас это лучше, но из документации не так очевидно, что это асинхронно.

Tholle 17.07.2018 16:41

Тогда мне повезло, наверное :). Да, документация не так понятна, я думаю, что следил за некоторыми хорошими учебниками, поэтому я не столкнулся с этой проблемой.

devserkan 17.07.2018 16:47

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