使用哪种 ReactJS 语法;React.createClass 还是 ES6 扩展?

IT技术 syntax reactjs ecmascript-6 react-jsx
2021-04-06 19:25:47

我是 ReactJS 的初学者。我在各种网站上学习和研究了很多文档和电子书。我意识到 ReactJS 有两种语法。例子:

React.createClass({
  displayName: 'Counter',
  getDefaultProps: function(){
    return {initialCount: 0};
  },
  getInitialState: function() {
    return {count: this.props.initialCount} 
  },
  propTypes: {initialCount: React.PropTypes.number},
  tick() {
    this.setState({count: this.state.count + 1});
  },
  render() {
    return (
      <div onClick={this.tick}>
        Clicks: {this.state.count}
      </div>
    );
  }
});

而这个版本是由 ES6 编写的:

class Counter extends React.Component {
  static propTypes = {initialCount: React.PropTypes.number};
  static defaultProps = {initialCount: 0};

  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }

  state = {count: this.props.initialCount};
  tick() {
    this.setState({count: this.state.count + 1});
  }

  render() {
    return (
      <div onClick={this.tick.bind(this)}>
        Clicks: {this.state.count}
      </div>
    );
  }
}

使用 ReactJS 的更好方法是什么?但是我发现这些库,github 上的应用程序曾经执行过很多 ES6。

3个回答

第二种方法可能是未来采用的正确方法,因为 Facebook 表示他们最终将弃用 React.createClass 方法。

来自React v0.13 发行说明

我们的最终目标是让 ES6 类完全替换 React.createClass,但是在我们替换当前的 mixin 用例并支持语言中的类属性初始化器之前,我们不打算弃用 React.createClass

我个人认为第二种方法也使代码更易于阅读,但这显然是一个更主观的原因。

但是,如上所述,重要的是要注意 ES6 格式不支持 Mixin,因此如果您需要 mixin,则需要对该组件使用 createClass 格式。

Todd Motto 的这篇文章“React.createClass vs extends React.Component”提供了一些关于两种语法之间差异的很好的信息。值得一读,以讨论this关键字在两种语法之间的行为方式有何不同。

编辑:Dan Caragea 下面的帖子提出了一些绝对应该考虑的优秀观点。

第三种选择...

还有第三种定义 React 组件的方法,在 React 文档中称为“无状态函数” ,通常称为“无状态功能组件”或“功能无状态组件”。这是文档中的示例:

function HelloMessage(props) {
  return <div>Hello {props.name}</div>;
}

将组件定义为函数意味着它每次都有效地重新创建,因此没有持续的内部状态。这使得组件更易于推理和测试,因为对于给定的一组属性(props),组件的行为将始终相同,而不是由于内部状态的值而可能在每次运行之间发生变化。

这种方法在使用单独的状态管理方法(例如 Redux)时特别有效,并确保 Redux 的时间旅行将产生一致的结果。功能性无状态组件还使诸如撤消/重做之类的功能的实现变得更简单。

我喜欢用的是复合方式,React.createClass。ES6 类只是糖,对使用工厂创建没有任何实际value(至少对我而言)。也许装饰器在 ES6 类中会派上用场,但可以通过使用高阶函数轻松实现。所以我的赌注是 ES6 + React.createClass === win
2021-05-22 19:25:47
感谢@tom 提供的信息和主观原因。以前,我喜欢用 JSX 语法来编写我的 ReactJS 项目。但是现在,我应该重新考虑决定用 ES6 语法编写 ReactJS。:) 谢谢
2021-06-01 19:25:47

我已经React.createClass为我的宠物项目完成了工作和 ES6 课程。我确实发现后者也更容易阅读,但我经常怀念前者的简单/安心。对于基于类的方法,请注意,从技术上讲,静态定义的 propTypes 和 defaultProps 是 ES7,而不是 ES6——这可能会在 ES7 最终确定之前发生变化。一个纯粹的 ES6 方法是声明 propTypes/defaultProps 像

class Counter extends React.Component {
...
}
Counter.propTypes = {...};
Counter.defaultProps = {...};

您还必须记住在渲染中绑定 onClick(或任何其他需要使用的方法this)。几乎可以肯定,您会在某些地方忘记。而在 createClass 中,所有调用都由 React 自动绑定。另一个 ES7 提案可以使事情变得更容易,但您仍然需要记住将其写在任何地方: <div onClick={::this.tick}>绑定thistick. 当然,您必须在 babel 配置中选择加入 stage 0 才能使用所有这些 ES7 建议。

关于 mixins……有一些可以接受的方法可以将 mixin 与类一起使用。一个绝妙的方法是mixWith.js但你也可以尝试 ES7 装饰器、HOCs,甚至Object.assign():)

归根结底,我觉得 class 方法并没有带来任何真正的value,在你对 React 有一个很好的理解之前,你可以走老式的 createClass 方法。然后你可以玩转类和 ES6/7/100。他们弃用还需要很长时间createClass

我从 React ES6 + staging style 开始,当你说在 React 中一切都是一个组件时,这听起来不错。我喜欢这个class组织。

在此处输入图片说明

因为class如果你想在纯 ES6 中定义属性,只能在 ES6 中定义方法,所以它们必须在类之外。例如在这里:

export class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }
  tick() {
    this.setState({count: this.state.count + 1});
  }
  render() {
    return (
      <div onClick={this.tick.bind(this)}>
        Clicks: {this.state.count}
      </div>
    );
  }
}
Counter.propTypes = { initialCount: React.PropTypes.number };
Counter.defaultProps = { initialCount: 0 };

这就是为什么在 ES6propTypes部分是在类定义之外的原因

但是如果你使用 ES7 你可以定义静态和非静态属性而不会在class.

// ES7
export class Counter extends React.Component {
  static propTypes = { initialCount: React.PropTypes.number };
  static defaultProps = { initialCount: 0 };
  state = { count: this.props.initialCount };
  tick() {
    this.setState({ count: this.state.count + 1 });
  }
  render() {
    return (
      <div onClick={this.tick.bind(this)}>
        Clicks: {this.state.count}
      </div>
    );
  }
}

随着ES7您可以使用方法也作为证明隐式绑定的技巧在这里

return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
);

旧的 pre React v0.13 风格或 ES5 风格是这样的。

在此处输入图片说明

React.createClass所有方法中都自动绑定了 this。

这对 JavaScript 开发人员来说可能有点混乱,因为这不是原生 JavaScript 行为。

这就是写:

class Counter extends React.Component {
  constructor() {
    super();
    this.tick = this.tick.bind(this);
  }
  tick() {
    ...
  }
  ...
}

或者使用一些技巧来使用属性初始值设定项语法来完成相同的操作。

class Counter extends React.Component {
  tick = () => {
    ...
  }
  ...
}

得出结论

对于新人来说,我觉得最新款是更好的选择。


关于 Mixin

如前所述这里

ES6 在没有任何 mixin 支持的情况下推出。因此,当您将 React 与 ES6 类一起使用时,不支持 mixin。我们还在使用 mixin 的代码库中发现了许多问题,不建议在新代码中使用它们。本节仅供参考。