Есть ли более простой способ установить статус в React? - PullRequest
0 голосов
/ 15 апреля 2020

Я новичок в React, и я искал более простой способ установки статуса. Одним из важных примечаний является то, что он был внутри функционального компонента.

    const [ personState, setPersonsState ] = useState({
      persons: [
        { name : 'Max', age : 28 },
        { name : 'Manu', age : 29 },
        { name : 'Stephanie', age : 26 }
      ]
    });

Я знаю, что обычно это что-то вроде этого, и это прекрасно работает.

    setPersonsState({
      persons: [
        { name : 'Max', age : 28 },
        { name : 'Ati', age : 29 },
        { name : 'Stephanie', age : 26 }
      ]

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

    const newState = personState;
    newState.persons[1].name = 'Ati';
    setPersonsState(newState)

Это не сработало, и я не не знаю почему. Когда я сохраняю их в console.log, он успешно меняется, но по какой-то причине состояние не обновляется, хотя я использую команду set. Я также заметил странное поведение React: когда я использовал эту команду newState.persons[1].name = 'Ati';, она также изменила переменную personState. Таким образом, переменные personState и newState выглядели так в консоли.

    {persons: Array(3)}
    persons: Array(3)
    0: {name: "Max", age: 28}
    1: {name: "Ati", age: 29}
    2: {name: "Stephanie", age: 26}
    length: 3
    __proto__: Array(0)
    __proto__: Object

Буду признателен за любую помощь или объяснение, почему это не работает.

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

Когда вы делаете эту строку const newState = personState; Вы не копируете объект в personState в newState, но вы берете ссылку на personState и заставляете newState ссылаться на это.

Когда вы вносите изменения в newState, это как если бы вы меняли personState, потому что ссылки на обе эти переменные одинаковы. Вы напрямую изменяете объект состояния, который в React запрещен, потому что он не go с жизненным циклом, и именно поэтому вы получаете это странное поведение.

Если вы хотите скопировать Для объекта содержимого этой новой переменной вам необходимо:

const newState = Object.assign({}, personState)

или использовать синтаксис Spread

const newState = { ...personState }

После этого вы можете go о настройке состояния с помощью setPersonState

Примечание. Если у вас есть вложенные объекты, указанные выше данные методы сделают только поверхностную копию, то есть будут скопированы только значения первого уровня.

Если вы хотите сделать глубокую копию объекта, вам придется либо сделать несколько разворотов объекта (что является распространенным шаблоном в управлении состоянием редукса), например,

let state = {a: "val", b: { c: "val" }}

let newState = {
    ...state, 
    b: { 
        ...state.b 
     }
}

или использовать loda sh s deepClone

например

var objects = [{ 'a': 1 }, { 'b': 2 }];

var deep = _.cloneDeep(objects);
0 голосов
/ 15 апреля 2020

В вашем коде вы пытаетесь напрямую изменить состояние. Вместо этого вы можете скопировать массив и изменить там нужное вам значение.

Я бы попытался обновить состояние, используя .map(), как показано ниже:

setPersonsState(prevState => ({
   persons: personState.map(e => {
      if (e.name === 'Manu') e.name = 'Ati';
      return e;
   }));
});

Надеюсь, это поможет!

...