Я новичок в React. Я не понимаю, почему эта проблема не работает.
У меня Numbers Component.
const Numbers = (props) => {
return(
<div className = "card text-center">
<div>
{Numbers.list.map((num,i) =>
<span key = {i} onClick = {() => props.selectNumbers(num)}>
{num}
</span>
)}
</div>
</div>
);
}
Numbers.list = [1,2,3,4,5,6,7,8,9];
Теперь в родительском компоненте Game ..
class Game extends React.Component {
state = {
selectedNumbers : []
};
selectNumber = (clickedNumber) => {
if (this.state.selectedNumbers.indexOf(clickedNumber) >= 0) {return;}
this.setState(prevState => ({
selectedNumbers: prevState.selectedNumbers.concat(clickedNumber)
}));
};
render() {
const {selectedNumbers } = this.state;
return (
<div className = "container">
<h3>
Play Nine
</h3>
<hr />
<div className = "row">
<Answer selectedNums = {selectedNumbers} />
</div>
<br />
<Numbers selectNumbers = {this.selectNumber} selectedNums = {selectedNumbers} />
</div>
);
}
}
Теперь эта штука работает нормально. Но когда я сделаю ...
this.setState(prevState => ({
selectedNumbers: prevState.selectedNumbers.push(clickedNumber)
}));
приложение работает должным образом.
As prevState.selectedNumbers is an array не должен ли он быть push, а не concat?
Что я делаю неправильно?



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


Когда вы используете push, вы устанавливаете selectedNumbers как возвращаемое значение операции push, которое является длиной нового массива в соответствии с документация разработчика Mozilla. Push также пытается изменить состояние массива, что, как сказал PhilippSpo, не работает.
Либо используйте concat, как раньше, либо скопируйте selectedNumbers в новый массив, вставьте свое значение в этот массив и затем установите selectedNumbers в новый массив. Если вы используете ES6, вы можете использовать оператор распространения, как указывали другие пользователи.
Как упоминалось в комментариях, толкать является изменяющейся функцией и возвращает длину результирующего массива. Вы можете использовать синтаксис распространения, чтобы легко протолкнуть новый элемент.
this.setState(prevState => ({
selectedNumbers: [...prevState.selectedNumbers, clickedNumber]
}));
Вы должны использовать функцию concat () вместо толкать(), потому что реакция не работает с изменчивостью объекта, люди реагируют, подчеркивают, что разработчики реагируют на сохранение состояния неизменяемости.
Когда вы используете функцию concat (), она всегда возвращает новый объект, а не изменяет тот же самый старый объект, поэтому вы никогда не должны использовать функцию толкать() в реакции, потому что push изменяет старый объект.
push - это мутирующая операция. Таким образом, вызов push в предыдущем состоянии попытался бы изменить его. Это похоже на попытку изменить историю. Что вы хотите сделать, так это создать новое состояние, повторно используя старое состояние, не изменяя его. Это то, что вы можете сделать с помощью concat или оператора распространения ES6.