Как setState в React работает в этом сценарии?
Я пытаюсь установить состояние объекта в моем массиве. Я достиг этого, но я не понимаю этого.
toggleVisited = countryCode => {
var countries = [ ...this.state.countries ];
var countryToChange = countries.find(country => country.code === countryCode);
countryToChange.visited = !countryToChange.visited;
this.setState({ countryToChange });
}
Я понимаю (в основном), что происходит, до последнего this.setState
линия.
Я изменил код на this.setState({})
и это все еще работало. Я всегда думал, что set state устанавливает новое значение для ключа объекта. Почему (независимо от того, что я вставил сюда), он все еще правильно настраивает?
3 ответа
С countryToChange.visited = !countryToChange.visited
, вы мутируете своим текущим состоянием. Не делай этого. Вместо этого создайте новый объект:
toggleVisited = countryCode => {
this.setState(prevState => {
const countries = prevState.countries.map(country => country.code !== countryCode
? country
: {
...country,
visited: !country.visited
})
const countryToChange = countries.find(country => country.code === countryCode)
return {
countries,
countryToChange
}
})
}
toggleVisited = countryCode => {
var countries = [ ...this.state.countries ];
//here you use spread operator to "clone" all countries
var countryToChange = countries.find(country => country.code === countryCode);
//you filter all your countries and get the one with the CC you want
countryToChange.visited = !countryToChange.visited;
//your country is an object, and you change visited prop to it's opposite
//boolean, !false == true
this.setState({ countryToChange });
//you just changed your country visited prop, in react you cannot change
//deep props so, you re-set {countryToChange: countryToChange}
//or simply {countryToChange} due to new ES features
}
Состояние компонента React должно рассматриваться как неизменяемое, но вы можете изменить его значения. Ваш код будет работать для каждого setState(), который вы делаете, потому что setState запускает повторный рендеринг, и так как вы уже изменили состояние countryToChange.visited = !countryToChange.visited;
, компонент будет перерисован с новым состоянием.