Я пытаюсь заменить изначально пустой массив массивом, созданным функцией, использующей 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>
);
}
}
В конструкторе должен быть не this.state({ sources: [] };, а this.state = { sources: [] };
Не могли бы вы опубликовать фрагмент метода, из которого вы вызываете setState
@Tholle, спасибо, это была опечатка в моем вопросе, в фактическом файле кода я написал правильно
Хорошо. Не могли бы вы включить весь свой компонент с таким поведением? Трудно сказать, что может быть не так в коде, который сейчас обсуждается в вашем вопросе.
вы уверены, что вызываете этот метод? где этот метод? как ты это называешь? когда вы проверяете, изменился ли state?
отредактирован, чтобы включить полный тестовый код
Вы пытаетесь получить к нему доступ сразу после установки состояния, это не работает. setState асинхронный.
@Rikin вау, спасибо, я понятия не имел. просто попытался вызвать извне метода, и он отлично сработал. Спасибо!!!!!!
именно поэтому я спросил when are you checking to see if state has changed. setState является асинхронным, поэтому, если вы проверите его сразу после этого, вы не увидите разницы, хотя изменения в состоянии были сделаны, подробнее здесь асинхронный setState
Возможный дубликат Почему вызов метода response setState не изменяет состояние немедленно?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вот пример, который должен работать так, как вы описываете:
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?
Ваш код работает, но вы не учитываете, что setState асинхронный. Если вы зарегистрируете this.state в обратном вызове, который можно указать в качестве второго аргумента для setState, он будет гарантировать, что он обновился.
this.setState({ sources: temp }, () => {
console.info(this.state.sources);
});
Мы почти каждый день сталкиваемся с одним и тем же вопросом. Почему люди не используют метод рендеринга для регистрации состояния? Я воздерживаюсь от ответа "Использовать метод рендеринга" вместо этого обратного вызова :)
@devserkan Я сам попался на это, когда начал использовать React. Я думаю, что сейчас это лучше, но из документации не так очевидно, что это асинхронно.
Тогда мне повезло, наверное :). Да, документация не так понятна, я думаю, что следил за некоторыми хорошими учебниками, поэтому я не столкнулся с этой проблемой.
здесь работает - codeandbox.io/s/l7j005yknz