使用构造函数与 state = {} 在 React 组件中声明状态有什么区别?

IT技术 javascript reactjs ecmascript-6 class-fields
2021-01-27 09:40:52

我发现有两种方法可以在类组件中声明状态,如下所示

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            name: 'John'
        }
    }

    render() {
        return  <div>{this.state.name}</div>
    }

}

class App extends Component {
    state = {
       name: 'John'
    }

    render() {
        return  <div>{this.state.name}</div>
    }

}

这两者有什么区别?

3个回答

它们大致相当。显着的区别在于第二个示例中的初始化程序在constructor.

第二种方法使用类字段提案。

它不是 ECMAScript 标准的一部分,因此您需要正确设置转译器才能使用第二种方法。

UPD查看Babel 输出以更好地了解公共实例字段的工作原理。

当您想将props数据保存时使用构造函数state

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      name: 'John'
    }
  }
}

否则你可以直接设置state硬编码数据

class App extends Component {
  state = {
    name: 'John'
  }
}
向状态添加道具通常被认为是一种反模式:reactjs.org/docs/react-component.html#constructor除非你想显式地导出状态
2021-03-25 09:40:52
显然这不再有效。我成功地在类 state = { time: this.props.time, }; 中直接将 props 值分配给 state
2021-04-11 09:40:52

当您向类添加方法时,它实际上被添加到函数的原型中。像这样:

class Same{
  thing() {}
}

// Equivalent to:

function Same() {}
Same.prototype.thing = function () {}

thing定义一次并在类的所有实例中共享。

如果您将其重构为使用类字段,如下所示:

class Animal {
  thing() {}
  anotherThing = () => {} // Class Field
}

// Equivalent to:

function Animal () {
  this.anotherThing = function () {}
}

Animal.prototype.thing = function () {}

anotherThing是在每个新创建的实例上定义的,而不是在原型上定义的。

开发经验与性能

这是您应该考虑的权衡。Class Fields 使您的代码看起来可读和干净。但是,类字段在您的每个实例中都保留了anotherThing的副本

因此,您应该仔细考虑是否要使用它们。

嗨@vikrant!如果我理解正确的话,您的问题来自 OOP 继承(如在 Java 中)。在 Java 中,构造函数确实为每个实例创建了 anotherThing。在 Javascript 中,事情的行为“略有不同”。原型链为每个实例保留对 anotherThing 的引用,这使它们变得轻量级和精简。一个很棒的系列丛书(由 Kyle Simpson 编写)阐明了 Javascript 基础的基本框架。我强烈建议您专门阅读本节:github.com/getify/You-Dont-Know-JS/blob/master/...
2021-03-19 09:40:52
“类字段在您的每个实例中都保留了 anotherThing 的副本”,这不正是构造函数所做的吗?
2021-03-22 09:40:52