An opinionated guide to React.js best practices and conventions

I’ve been using React.js for a little while now, both in my 9 to 5 job and for my own projects, and during that time I have started evolving my own set of React.js best practices.

The following guidelines mostly focus on component structure and JSX. However, they are not hard and fast rules, but more of an opinionated set of guidelines I choose to adhere to that make my code more readable, more robust and easily maintainable.

Note: This article does not provide explanations of the React paradigms or idioms mentioned here or used in the examples, that is best left to the excellent documentation provided by the React team.

Component organisation

As with any code, it’s important to have consistency. This of course also applies when structuring your React components. I use the following pattern:


    React.createClass({

        propTypes: {},
        mixins : [],

        getInitialState: function() {},
        getDefaultProps: function() {},

        componentWillMount : function() {},
        componentWillReceiveProps: function() {},
        componentWillUnmount : function() {},

        _parseData : function() {},
        _onSelect : function() {},

        render : function() {}

    })

I like to declare propTypes at the top of my component as they are a useful guide to a components expected usage (see section below for more on this), followed by the mixins because it is handy to initially know exactly what external behaviours the component is using/dependent on.

I choose to split the life-cycle methods into those that occur before an instance of the component is created (e.g. getInitialState, getDefaultProps) and those which occur during the mounting/updating/mounted cycle (e.g. componentWillMount, shouldComponentUpdate). Furthermore, I find that declaring the lifecycle methods in order of execution also makes the component easier to reason about.

I always have my custom methods follow the lifecycle methods and be prefixed with an underscore to make them easier to identify. I’ll usually also group these by utility (parsers, event handlers, etc).

I like the render method to always be last. The render method is a mandatory lifecycle method and it’s almost always the function I need to find first when I open a file. Consequently, it’s pragmatic to have it in a consistent location across all of my components.

In general, my mixins will follow the same conventions as regular components.

Always set propTypes for validation and self-documentation

I always use propTypes to provide validation for each prop the component will receive. Furthermore, this also provides a self-documenting reference for how the component should be used, and what props it needs to be passed.


    propTypes: {
        arrayProp: React.PropTypes.array,
        boolProp: React.PropTypes.bool,
        funcProp: React.PropTypes.func,
        numProp: React.PropTypes.number,
        objProp: React.PropTypes.object,
        stringProp: React.PropTypes.string,
    }

JSX

Let’s face it, JSX can look pretty ugly at times and is one of the more common reasons developers are put off by React. However, by following a few general guidelines for handling JSX in components, it’s far more readable and not such an eyesore.

Multi-line JSX

No matter how few elements are being returned, I choose to write any JSX which contains nested elements across multiple lines with indentation to enhance readability, i.e:


    return (
        <div>
            <ComponentOne />
            <ComponentTwo />
        </div>
    );

Rather than…


    return (<div><ComponentOne /><ComponentTwo /></div>);

Furthermore, while the parenthesis are not technically required with a single line JSX statement, I still use them for the sake of consistency (and because unrestrained elements floating about in my JS makes my left eye twitch uncontrollably).

Conditional JSX

When I have conditional elements that needs to be returned depending on state, props, or another condition, I declare an empty variable at the top of the render function and only populate it with JSX if the condition is met. When the variable is returned in the render method return statement, it’ll either render the conditional elements, or nothing at all.


    var optionalElement;

    if (this.props.condition) {
        optionalElement = (<div> … </div>);
    }

    return (
        <div>
            …
            {optionalElement}
            …
        </div>
    );

In-line list iteration

Where possible, I like to iterate over lists of data in-line in the returned JSX unless its internal logic is sufficiently complex enough to warrant moving outside of the return statement and populating an array for rendering.


    return (
        <div>
            {this.props.list.map(function(data, i) {
                return (<Component data={data} key={i} />)
            })}
        </div>
    );

Indentation and new line for component attributes

When there are enough attributes on a component that displaying them inline becomes untidy (usually 3 or more), I always display them on multiple lines and indent each one. i.e.


    <Component
        attribute={...}
        anotherAttribute={...}
        attributeThree={...}
        …
    />

Rather than…


    <Component attribute={...} anotherAttribute={...} attributeThree={...} />

Conclusion

These guidelines are by no means authoritative or exhaustive, but I feel they are a good starting point for organising and standardising React components and some of the more common use cases I encounter.

Hopefully these guidelines provide a useful starting point for organising your React components. Be sure to leave a comment if you have a question!

Want to become a better web developer?

Join over 25,000 other developer & designers who get awesome links to the best news and articles each week delivered directly to their inbox.

John Cobb

Front End Engineer in Sydney, Australia. I know a thing or two. Maybe three. Probably two.

38 Comments

  1. Very good starting point for ‘ReactJS Style guide ‘ . Thanks for the article

  2. Cool! Thanks for the tips!

  3. Nice article!
    Link of “excellent documentation” is “http://http//facebook.github.io/react/docs/”.

    • Nice catch, fixed 🙂

  4. Can you update one example of react with flux

    • Hi John Cobb, nice sharing, but if you are using es6/es2015, your code will look some what different.

  5. great, great article – so clear and concise

  6. Wow! Rarely do I read a style guide and agree with every single point. This is exactly the same as our guide for our huge React codebase in Atlas at Facebook. Here are a few more we have found helpful:

    – PropType declarations should be grouped into required then non-required separated by a new line, and each group alphabetically sorted. Props passed to a component should be alphabetically sorted without regard to required status.
    – Always use a component level function as an event handler. Instead of onClick={SomeActionCreator.someAction}, do onClick={this._someButtonClicked}, and call SomeActionCreator.someAction inside. This mostly came out of a bug where an optional parameter was added to an action creator call, and it was then being passed the Event object.
    – I personally prefer inline ternaries for conditional rendering, but we also use the style you suggested often.

    • Thank for your input Ian!

      It’s always great to hear what people are doing on the frontline.

    • Hey Ian, thanks for your comment! Really great to hear that you use a similar set of guidelines in Atas.

    • How do your ternaries look like?
      I had used this:

      return (

      {this.props.showElement ? () : void(0)}

      );

  7. Great style guide! Can you provide a version that uses ES6 classes, as per the latest update? http://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html

    • Hey David – seeing as using the ES6 classes don’t add any great benefit over using the standard React.createClass and usage comes with some constraints/downsides (Unable to use Mixins, imperative property assignment for propTypes, defaultProps, etc), I personally don’t have any plans to start using the ES6 classes any time soon.

      However, the bulk of my guidelines (component structure, JSX related rules) would still apply to the ES6 classes.

    • Nice sharing John thanks !

      About the conditional JSX, what do you think about the following :

      if(this.props.expired){
      return (…);
      }else{
      return (..);

    • Stéphane,

      I would assign the result of the evaluation block to a variable and return that. I prefer to only have one exit point out of a function if I can help it. It makes it easier to reason about if you don’t have to look for multiple exit locations.

  8. Thanks, this is a nice post. Something I’ve been curious about, maybe something you’d be willing to write about sometime: how do you organize component files themselves? Do they get organized by page, or by purpose? It’s still somewhat of an open question to me since a lot of my components are not bound to a single specific page.

  9. Thanks! So precise and shows a proper direction to write react apps.

  10. Great post. Thanks!

  11. This is a great starting point to discuss React best practices.

  12. I got this article recommended by a friend. Really appreciate you took the time to write this guide.

  13. Great and well-written article. Thank you for this. Cheers!

  14. Hi John Cobb, nice sharing, but if you are using es6/es2015, your code will look some what different.

  15. What’s the best way to comment inside a react js file? this has led to issues as // comments cause errors.

    I was working on some components named for example Profile.js and commented with “//” so I could reference some logic I used later when I go back and look at it. Thanks!

  16. I’m just a beginner with react.js , I was searching for a way to document my component.
    This page helped me a lot 🙂
    Thanks you

  17. Its a wonderful post. I like the information provided here.

  18. It’s worth pointing out that key={i} “silences React” but does so by entirely ignoring what the key is for. An array can be reordered, so the key property is for making sure that even if moved to a different spot, React knows it’s the same element, something that key={i} explicitly negates. You want to pass some “unique” value in as key, extracted from the data you’re using in your map

  19. Nice article, let me learn Reactjs a lot.

  20. Great post! Exactly what I need to start using ReactJS.
    Thanks!

  21. I have created some react components, which opens on click of div and on close I get hold of the node, and unmountComponentAtNode and remove it. Though it seems it doesn’t really remove the component. Because in the Chrome Debug React Console, it shows the two components with the same values. Is it expected behavior that it doesn’t update in the chrome?

    thanks.

  22. Do you have any conventions on how to name companents ?

  23. Hey John,

    Excellent article. One thing I have found very useful to enforce is comments with details about propTypes. For example:

    propTypes: {
    someStuff: React.PropTypes.array // object literals with user id and name
    }

  24. https://github.com/airbnb/javascript/tree/master/react#methods

    Do not use underscore prefix for internal methods of a React component.

    ^_^

  25. Good one 🙂

  26. Thanks for the write up, it’s helped me out a lot 🙂

  27. Just started using react a few days ago. Still not sure about the best patterns and practices within react. Is it common to pass say functions for executing after an update in a react component to update something else in external ( non component code ).

    Like if my react component had an event property with events: { update: null, remove: null }

    so that after I instantiate my component the user can define.

    var myComp = React.Render(, placeToMount);

    myComp.events.update = function() {
    console.log(“updated”);
    }

    obviously there would be a check if the event.update function was null in whatever code would handle the update.

    I’m guessing it’s not a standard as you would probably just include that as another component within your component.

  28. Great advice. One question: do you use browserify/reactify? How do you split up components between files? How do you associate them with their requisite stores (when the stores are in different files?)

  29. Useful article.

This post currently has 38 responses. What do you think?

You can use basic HTML when posting code, please turn all < characters into &lt; or > into &gt;
If the code is multi-line, use <pre><code></code></pre>

Leave a Reply

Your email address will not be published. Required fields are marked *