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

时间:2016-01-28 10:00:15

标签: syntax reactjs ecmascript-6 react-jsx

我是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 个答案:

答案 0 :(得分:11)

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

来自React v0.13 release notes

  

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

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

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

This post "React.createClass versus extends React.Component" by Todd Motto有两个关于两种语法之间差异的好信息。值得一读的是,讨论this关键字在两种语法之间的行为方式有何不同。

编辑:Dan Caragea's post below提出了一些绝对值得考虑的优点。

第三种选择......

还有第三种定义React组件的方法,称为“无状态函数”。 in the React Documentation并经常被称为“无状态功能组件”。或者&#39;功能无状态组件&#39;。这是文档中的示例:

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

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

这种方法在使用Redux等单独的状态管理方法时效果特别好,并确保Redux的时间旅行能够产生一致的结果。功能无状态组件还可以实现诸如撤消/重做更简单的功能。

答案 1 :(得分:5)

我为我的宠物项目完成了React.createClass工作和ES6课程。我发现后者也更容易阅读,但我常常想念我与前者的简单/安心。 使用基于类的方法,请注意,从技术上讲,静态定义的propTypes和defaultProps是ES7,而不是ES6 - 在ES7最终确定之前可能会更改。 纯ES6方法是声明propTypes / defaultProps,如

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

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

关于mixins ......有一些方法可以将mixins与类一起使用。一个很棒的方法是mixWith.js,但您也可以尝试ES7装饰器,HOC,甚至是Object.assign():)

在一天结束时,我觉得课程方法并没有带来任何真正有价值的东西,你可以使用createClass的旧方法,直到你对React有一个很好的理解。然后你可以玩类和ES6 / 7/100。他们弃用createClass之前需要很长时间。

答案 2 :(得分:0)

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

enter image description here

因为如果要在纯ES6中定义属性,只能在ES6 class内定义方法,因此它们必须在类之外。比如在这里:

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 };

这就是ES6 propTypes部分超出类定义的原因。

但是如果您使用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,您可以使用方法的隐式绑定提示,如here

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

旧的React v0.13样式或ES5样式就是这样。

enter image description here

React.createClass中,所有方法都会自动绑定。

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

这是写道:

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

或使用一些技巧来使用属性初始化器语法来完成相同的操作。

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

由此得出结论

对于新手来说,我认为最新款式是更好的选择。

关于Mixins

如上所述here

  

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