Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which ReactJS syntax to use; React.createClass or ES6 extends?

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.

like image 523
Pham Minh Tan Avatar asked Jan 28 '16 10:01

Pham Minh Tan


People also ask

What is createClass in React?

React. createClass allows you to generate component "classes." Under the hood, your component class is using a bespoke class system implemented by React. With ES6, React allows you to implement component classes that use ES6 JavaScript classes.

Does Reactjs use ES6?

React uses ES6, and you should be familiar with some of the new features like: Classes. Arrow Functions. Variables (let, const, var)

Is React createClass deprecated?

As of React 15.5, createClass is deprecated. You'll get warnings in the console if you're using it in your code – and, when React 16 comes out, createClass will be removed entirely.

What is the React class which it needs to extend from?

For the React changes, we now create a class called “Contacts” and extend from React. Component instead of accessing React. createClass directly, which uses less React boilerplate and more JavaScript. This is an important change to note further changes this syntax swap brings.


2 Answers

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.

like image 114
tomRedox Avatar answered Oct 13 '22 11:10

tomRedox


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.

like image 42
Dan Caragea Avatar answered Oct 13 '22 10:10

Dan Caragea