Неизменность и обновление вложенного ключа локального состояния - PullRequest
2 голосов
/ 04 октября 2019

У меня следующее состояние.

state = {
  friends: {
    nickNames: ['Polly', 'P', 'Pau'],
    ... here more k:v
    },
  }
}

И я хочу обновить массив nickNames значением, полученным из неконтролируемой формы через метод в моем классе. Тем не менее, у меня возникают проблемы во время определения, правильно ли я устанавливаю состояние, не изменяя его.

Я делаю следующее

updateArray = (nickName) => {

  const tempDeepCopy = {
    ...this.state,
    friends: {
      ...this.state.friends,
      nickNames: [...this.state.friends.nickNames]
    }
  }

  tempDeepCopy.friends.nickNames.push(nickName)

  this.setState({
    friends: 
    {
      nickNames: tempDeepCopy.friends.nickNames
    }
  })

}

Это правильный способ сделатьЭто? Если да, то является ли это также наиболее эффективным, учитывая состояние? Я стараюсь избегать вспомогательных библиотек, чтобы научиться делать глубокие копии.

Я буду признателен за помощь, поскольку я пытаюсь научиться неизменности, и эта концепция требует от меня много усилий.

Ответы [ 4 ]

4 голосов
/ 04 октября 2019

setState() в компонентах класса выполняет мелкое слияние.

Таким образом, вы можете просто игнорировать другие «родительские» ключи и сосредоточиться только на friends.

YouМожно также упростить это как:

this.setState({
  friends: { // only focus on friends
    ...this.state.friends, // do not ignore other friend k:v pairs
    nicknames: [
      ...this.state.friends.nicknames,
      nickName
    ]
  }
})
2 голосов
/ 04 октября 2019

Почему бы просто;

updateArray = (nickName) => {

  const updatedNickNames = [...this.state.friends.nickNames, nickName];

  this.setState({
    friends: {
      ...this.state.friends,
      nickNames: updatedNickNames
    }
  });

}

Поскольку nickNames - это просто массив строк, вы можете скопировать его с помощью оператора распространения. Кроме того, с помощью setState вы можете изменить определенную часть вашего состояния, в вашем случае вам нужно беспокоиться только о части friends.

0 голосов
/ 04 октября 2019

Это правильный способ сделать это. Дело в том, что вы никогда не должны менять состояние напрямую. Вот и все.

Я мог бы дать более краткий код

state = {
  friends: {
    nickNames: ['Polly', 'P', 'Pau'],
    ... here more k:v
    },
  }
}

updateArray = (nickName) => {
  this.setState(prevState => ({
    ...prevState,
    friends: 
    {
        ...prevState.friends,
        nickNames: [...prevState.friends.nickNames, nickname]    
    }
  }))

}

Пока вы не изменяете состояние напрямую, любой способ будет действовать через setState ()

0 голосов
/ 04 октября 2019

Вы можете просто использовать

this.setState({
    friends: 
    {
      nickNames: [...this.state.friends.nickNames, nickName]
    }
  })

Состояние должно быть изменено только через функцию setState, потому что, если вы измените его напрямую, вы можете нарушить компонент React lyfecycle.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...