Как setState в React работает в этом сценарии? - PullRequest
0 голосов
/ 13 января 2019

Я пытаюсь установить состояние объекта внутри моего массива. Я достиг этого, но не понимаю.

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 ]

0 голосов
/ 14 января 2019

Состояние компонента React должно рассматриваться как неизменяемое, но вы можете изменить его значения. Ваш код будет работать для каждого setState (), который вы делаете, потому что setState вызывает повторную визуализацию, и, поскольку вы уже изменили состояние countryToChange.visited = !countryToChange.visited;, компонент будет повторно визуализирован с новым состоянием.

0 голосов
/ 14 января 2019
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
}
0 голосов
/ 14 января 2019

С 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
        }
    })
}
...