Реакция изменений состояния при изменении назначенной переменной - PullRequest
6 голосов
/ 09 марта 2020

У меня возникла странная проблема с React.

this.state={
      testState: { testValue: "Test State" }
}
   
testFn = () => {
        let a;
        a = this.state.testState
        a.testValue = "Debugging is awesome";
        console.log(this.state.testState)
    }

Если я внес какие-либо изменения в назначенную переменную a, то это также отразится и в состоянии.

То, что я получил в консоли, это ,

{testValue: "Debugging is awesome"}.

Любая помощь будет ощутимой

Редактировать: Я не хочу менять состояние. Я должен изменить a без изменения состояния. Как мне этого добиться?

Ответы [ 7 ]

8 голосов
/ 09 марта 2020

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

this.setState({ testState: { testValue: "Debugging is awesome" } });

Если вы не хотите изменять состояние, вы можете использовать оператор распространения:

let a = { ...this.state.testState };
5 голосов
/ 09 марта 2020

Почему это так?

Это потому, что objects и arrays в JavaScript являются справочными значениями. Где бы вы ни обновляли его значение, он также обновляет источник. В этом случае вы бы хотели сделать его неизменным. Вы бы сделали это, назначив новый объект. В ES6 это можно сделать с помощью spread operator.

Solution

let a = { ...this.state.testState };

Дополнительная информация

4 голосов
/ 09 марта 2020

Вы должны глубоко скопировать состояние, если не хотите, чтобы оно было выполнено ( Object.assign ):

this.state={
  testState: { testValue: "Test State" }
}

testFn = () => {
    let a;
    a = Object.assign({}, this.state.testState);
    a.testValue = "Debugging is awesome";
    console.log(this.state.testState)
}

Или вы можете использовать {...this.state.testState} вместо Object.assign

Обратите внимание, что использование оператора распространения {...} не сохранит свойство прототипа (instanceof).

2 голосов
/ 09 марта 2020

Используя JS, когда вы воздействуете на объект переменной (здесь testState), он передается по ссылке (см. здесь для дальнейшего объяснения).

Это означает, что если вы измените объект с помощью одной из переменных, то к каждой переменной, ссылающейся на источник, будет применено изменение.

Чтобы решить вашу проблему, вы можете использовать оператор распространения, который копирует объект, не ссылаясь на него напрямую. :

let a = {...this.state.testState}
2 голосов
/ 09 марта 2020

Вы можете использовать оператор распространения для создания копии объекта

const newObj = {...obj};
1 голос
/ 09 марта 2020

Вы должны использовать оператор распространения (...) для этого вместо прямого присвоения.

this.state={
      testState: { testValue: "Test State" }
}
   
testFn = () => {
        let a;
        a = {...this.state.testState}
        a.testValue = "Debugging is awesome";
        console.log(this.state.testState)
    }
    
testFn()
0 голосов
/ 09 марта 2020

попробуй:

this.state={
      testState: { testValue: "Test State" }
}

testFn = () => {
        const a = { ...this.state.testState };
        a.testValue = "Debugging is awesome";
        console.log(this.state.testState)
    }
...