8

I'm beginner of ReactJS. I learned and studied a lot of documents and ebooks on various websites. I realize there are two syntaxes for ReactJS. Example:

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

And this version is written by 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>
    );
  }
}

What is the better way to use ReactJS? But I found these libraries, application on github used to perform a lot ES6.

tomRedox
  • 28,092
  • 24
  • 117
  • 154
Pham Minh Tan
  • 2,076
  • 7
  • 25
  • 37
  • when you have the chance you may set the title to "React.createClass vs. React.Component" I think this will be very good @PhamMinhTan – prosti Feb 01 '17 at 07:22

3 Answers3

11

The second approach is probably the correct one to adopt going forward as Facebook have said they will ultimately deprecate the React.createClass approach.

From the React v0.13 release notes:

Our eventual goal is for ES6 classes to replace React.createClass completely, but until we have a replacement for current mixin use cases and support for class property initializers in the language, we don't plan to deprecate React.createClass

Personally I think the second approach also makes for easier to read code, but that is obviously a more subjective reason.

However, as stated above, it's important to note that the ES6 format does not support Mixins, so if you need a mixin you need to use the createClass format for that component.

This post "React.createClass versus extends React.Component" by Todd Motto has some good information on the difference between the two syntaxes. It's worth reading that for a discussion of how the this keyword behaves differently between the two syntaxes.

Edit: Dan Caragea's post below makes some excellent points that should definitely be considered too.

A third alternative...

There is a also a third way of defining a React component, called 'Stateless Functions' in the React Documentation and often called 'Stateless Functional Components' or 'Functional Stateless Components'. This is the example from the docs:

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

Defining the component as a function means it is effectively created anew each time and so has no ongoing internal state. This makes the component easier to to reason about, and to test, as the component's behaviour will always be identical for a given set of properties (props), rather than potentially varying from run-to-run due the values of the internal state.

This approach works particularly well when using a separate State management approach such as Redux and ensures that Redux's time-travel will produce consistent results. Functional Stateless Components also make implementing features like undo/redo simpler.

Community
  • 1
  • 1
tomRedox
  • 28,092
  • 24
  • 117
  • 154
  • 1
    Thanks @tom for your information and your subjective reason. Before, I like JSX syntax to code my ReactJS project. But now, I should re-think to decide write ReactJS by ES6 syntax. :) Thank you – Pham Minh Tan Jan 28 '16 at 10:47
  • What I like to use is composite way, React.createClass. ES6 classes are just sugar without any real value against creating by using factory (at least to me). Maybe decorators would play in handy for ES6 classes, but that can easily be aided by using high order functions.. So my bet is ES6 + React.createClass === win – gor181 Jan 28 '16 at 11:27
5

I have done React.createClass for work and ES6 classes for my pet project. I do find the latter easier to read too but I often miss the simplicity/peace of mind I have with the former. With the class based approach, do note that, technically, the statically defined propTypes and defaultProps are ES7, not ES6 - which might change until ES7 is finalized. A pure ES6 approach would be to declare propTypes/defaultProps like

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

You also have to remember to bind onClick in render (or any other method where you need to use this). It's almost certain you will forget to in some places. While with createClass all calls are auto-bound by React. Another ES7 proposal could make things easier but you'd still need to remember to write it everywhere: <div onClick={::this.tick}> which binds this to tick. Of course, you'd have to opt in to stage 0 in babel config to make use of all these ES7 proposals.

About mixins...there are acceptable ways of using mixins with classes. A brilliant approach is mixWith.js but you could also try ES7 decorators, HOCs, even Object.assign() :)

At the end of the day, I feel that the class approach doesn't bring anything of real value and you could go the old and paved way of createClass until you have a good understanding of React. Then you can toy around with classes and ES6/7/100. It will be a long while before they deprecate createClass.

Dan Caragea
  • 1,784
  • 1
  • 19
  • 24
0

I started with React ES6 + staging style and it sounds nice when you say in React everything is a component. I like this class organization.

enter image description here

Because only methods can be defined inside ES6 class if you want to define properties in pure ES6 they have to be outside of the class. Like for instance in here:

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

This is why in ES6 propTypes section is outside of the class definition.

But if you use ES7 you can define static and non-static properties without a problem inside of the 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>
    );
  }
}

With ES7 you can use implicit binding tips for methods also as demonstrated in here:

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

The old pre React v0.13 style or ES5 style was like this.

enter image description here

In React.createClass all methods are bound this automatically.

This can be a little confusing for JavaScript developers because this is not native JavaScript behavior.

This is whe write:

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

or use some tricks to accomplish the same using property initializer syntax.

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

Conclude

For the newcomers, I think the latest style is a better choice.


About Mixins

As stated here:

ES6 launched without any mixin support. Therefore, there is no support for mixins when you use React with ES6 classes. We also found numerous issues in codebases using mixins, and don't recommend using them in the new code. This section exists only for the reference.

Community
  • 1
  • 1
prosti
  • 42,291
  • 14
  • 186
  • 151