React.js рекомендует назначать реквизиты непосредственно в состояние

Было выдано предупреждение React.js:

IndexPage: не рекомендуется назначать реквизиты непосредственно состоянию, поскольку обновления реквизитов не будут отражаться в состоянии. В большинстве случаев лучше использовать реквизит напрямую.

У меня был следующий код:

    class IndexPage extends React.Component<IProps, IState> {
       constructor(props) {
          super(props)
          this.state = props
       }
    }

Но когда я изменил свой код на:

    class IndexPage extends React.Component<IProps, IState> {
       constructor(props) {
          super(props)
          this.state = {...props}
       }
    }

Предупреждение исчезло.

Не могли бы вы объяснить, почему?


person Aidos Omurzakov    schedule 23.01.2020    source источник
comment
Это также решило мою проблему.   -  person Zach    schedule 30.11.2020


Ответы (1)


Из-за того, как работает присвоение значений объекта JS, присвоение одного объекта другому означает, что вторая переменная будет «указывать» на тот же экземпляр или содержать ссылку на него:

let x = { v: 1 };
let y = x;
x.v = 2;
console.log(y.v) // prints "2"

Предупреждение предназначено для предотвращения случайных предположений о том, что свойства автоматически «распространяются» на состояние. IOW, это работает не так, как вы обычно ожидаете:

// assume props = { v: 1 };
this.state = props;
// now props changes to { v: 2 };
console.log(this.state.v) // still prints 1, and that's why you get the warning

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

person Bartek Banachewicz    schedule 23.01.2020