12

I was looking at this fiddle for MobX and I've seen these two ways of defining React Components in ES6 other places as well, like Dan Abramov's egghead redux video series.

@observer
class TodoListView extends Component {
    render() {
        return <div>
            <ul>
                {this.props.todoList.todos.map(todo => 
                    <TodoView todo={todo} key={todo.id} />
                )}
            </ul>
            Tasks left: {this.props.todoList.unfinishedTodoCount}
        </div>
    }
}

const TodoView = observer(({todo}) =>
    <li>
        <input
            type="checkbox"
            checked={todo.finished}
            onClick={() => todo.finished = !todo.finished}
        />
        <input
            type="text"
          value={todo.title}
          onChange={ e => todo.title = e.target.value } />
    </li>
);

My question is, when is it appropriate to use each type?

It seems like the simpler components are able to use the simpler syntax, but I'd like a rule or guideline to follow.

Thanks!

Leventix
  • 3,789
  • 1
  • 32
  • 41
Grant Eagon
  • 1,400
  • 1
  • 12
  • 24

2 Answers2

19

The second pattern is called "stateless functional components", and using it is recommended in almost all cases. SFCs (stateless functional components) are pure functions that are only dependent on their props. They are easier to test, decoupled from each other and will have significant performance gains over other patterns in the future. (source from the official react documentation)

They have a few gotchas though, namely:

  • One cannot attach refs to SFCs. (src, src2)
  • They cannot have internal state. (src)
  • They cannot use lifecycle methods. (e.g. componentDidMount, src)

If you need any of these things, first make sure there is no way around using them and only then use either the ES6 class or the React.createClass patterns.


I highly recommend "Should I use React.createClass, ES6 Classes or stateless functional components?" by James K Nelson to understand the tradeoffs and difference between these patterns, and "Presentational and Container Components" by Dan Abramov for an explanation of the most commonly used structure for Redux applications.

mxstbr
  • 11,087
  • 4
  • 39
  • 37
  • 1
    Great answer! Thanks! – Grant Eagon Mar 01 '16 at 14:44
  • "using it is recommended in almost all cases." I would suggest revising that, as it's not really good advice and many will probably stop reading there. – rossipedia Mar 01 '16 at 15:39
  • How is it not good advice @rossipedia? I'm pretty sure it's true! – mxstbr Mar 01 '16 at 15:54
  • As you mentioned, there are many considerations to using standard components vs functional components. Calling them "recommended" (which isn't actually accurate) tends to stop people from actually thinking about them. The big issue is performance. Pushing a poorer performing solution as "recommended" causes the overall perception of React to become worse. – rossipedia Mar 01 '16 at 16:50
  • Functional components have their place (and technically don't need to be stateless, as you can give them state with closures), but they aren't a replacement at all for standard components with lifecycles. – rossipedia Mar 01 '16 at 16:51
  • I agree that they are not a full replacement, no doubt, but most components should be stateless functional components. (See the article by Dan for more information) – mxstbr Mar 01 '16 at 17:00
  • I don't know about SFCs being less performant than other patterns – do you have a source for that? In fact, I'm pretty sure SFCs are (or at least will be soon) more performant than any other method of creating components. – mxstbr Mar 01 '16 at 17:01
  • Also, if you look at the official documentation about stateless functions (https://facebook.github.io/react/docs/reusable-components.html#stateless-functions), you'll see the following sentence: "This is the recommended pattern, when possible.", which is pretty much what I'm saying in my comment. – mxstbr Mar 01 '16 at 17:02
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/105030/discussion-between-mstoiber-and-rossipedia). – mxstbr Mar 01 '16 at 17:06
0

React.createClass VS ES2015 classes VS functional stateless components

In React, there are 3 main ways of creating a new component.

The first one to be introduced alongside with React library was React.createClass, which has the following syntax:

var TestComponent = React.createClass({
 render: function(){
      return <p>{this.props.children}</p>;
 }
})

React.render(<TestComponent>This will be a paragraph element!</TestComponent>, document.body);

After that, in React 0.13 release, we could define our components directly as ES2015 classes:

class TestComponent extends React.Component {
 render () {
      return <p>{this.props.children}</p>;
 }
}

React.render(<TestComponent>This will be a paragraph element!</TestComponent>, document.body);

React 0.14 introduces the ability to create those called stateless components, also known as functional or pure components because they are declared as a function that has no state and returns the same markup given the same props:

const TestComponent = (props) => <p>props.children</p>;

ReactDOM.render(<TestComponent>This will be a paragraph element!</TestComponent>, 
document.querySelector('#root'));

These stateless components are much more lighter for React to render, and also have the advantage of being React agnostic, meaning that they can be rendered in any other way given the same input and will produce the same output.

So what you should use in your app depends. Each has their pros and cons and should be used under certain conditions. There are times when you can't use stateless components.

Use ES2015 (ES6) classes or React.createClass when your component needs lifecycle methods or you need to access 'this' for anything other than props.

esewalson
  • 240
  • 3
  • 2