在构造函数中定义状态还是使用属性初始值设定项更好?

IT技术 reactjs ecmascript-next
2021-04-20 02:17:49

根据这个babel 文档,在 React 中使用 ES6+ 的正确方法是像这样初始化组件:

class Video extends React.Component {
  static defaultProps = {
    autoPlay: false,
    maxLoops: 10,
  }
  static propTypes = {
    autoPlay: React.PropTypes.bool.isRequired,
    maxLoops: React.PropTypes.number.isRequired,
    posterFrameSrc: React.PropTypes.string.isRequired,
    videoSrc: React.PropTypes.string.isRequired,
  }
  state = {
    loopsRemaining: this.props.maxLoops,
  }
}

但是一些官方示例,例如 Dan Abramov 自己的React DnDmodule,使用 ES6+ 但仍然在构造函数中定义状态:

constructor(props) {
    super(props);
    this.moveCard = this.moveCard.bind(this);
    this.state = {
       // state stuff
    }
}

现在 Dan Abramov 作为 React 的重要贡献者,可能知道他可以在构造函数之外定义状态,但仍然选择在构造函数中进行。

所以我只是想知道哪种方式更好,为什么?

3个回答

我相信这是个人喜好的问题。转换后的输出在语义方面是相同的。

如果类extends React.Component,它们不会转换为相同的东西
2021-05-31 02:17:49
是的,足够公平,但是 的语义this.state没有改变。
2021-06-19 02:17:49

它们是等价的,因为类字段提议是构造函数主体代码的语法糖。

如果不需要显式构造函数(创建临时局部变量等),constructor可以省略以支持类字段。

显式构造函数的问题是super参数 ( props) 经常被错误地省略,这可能会导致问题:

constructor() {
    super();
    this.state = { foo: this.props.foo } // this.props is undefined
}

显式构造函数可能有益于可读性。方法是常规放置在下面constructor,甚至是箭头属性。这不会按预期工作,因为类字段是按照它们列出的顺序分配的:

state = { foo: { method: this.someMethod } } // this.someMethod is undefined

someMethod = () => ...;

在这种情况下,显式构造函数可能会导致代码更具可读性:

constructor(props) {
    super(props);

    // <-- this is the place where this.someMethod is really assigned

    this.state = { foo: { method: this.someMethod } }
}

someMethod = () => ...;

Dan 的代码实际上有一个微妙的错误,这就是为什么我建议尽可能使用初始化程序。React 组件构造函数接受两个参数 - props 和context他没有将它传递给父构造函数,其他一些需要它的开发人员很容易错过它。

有时您别无选择,例如当初始化程序依赖于构造函数参数时,因此请记住将所有参数传递给父级。

在尝试了几件事之后,看起来 React 没有我想到的问题。您可以将任何您想要的传递给父构造函数,它会很好。例如:

class MyComponent extends React.Component {
  constructor(props) {
    super({})
  }

  render() {
    // this.props will still be set correctly here
  }
}

我仍然建议使用初始值设定项,因为不必调用父构造函数是少要考虑的一件事。

“你可以将任何你想要的传递给父构造函数,它会很好” - 不。facebook.github.io/react/docs/react-component.html#constructor 以及: facebook.github.io/react/docs/state-and-lifecycle.html
2021-05-28 02:17:49
这是一种将数据传递到层次结构中更深层次的组件的方法,而无需在所有中介上设置 props。我尝试了一些测试,看起来 React 没有我提到的问题。不过,点仍然有效。
2021-05-29 02:17:49
我不知道 React 构造函数有两个参数。上下文是什么?
2021-06-01 02:17:49
文档并不总是与现实相符。并不是说人们应该忽略文档,只是指出 React 在实际中的行为有所不同。 github.com/facebook/react/blob/...
2021-06-11 02:17:49