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!
Very good starting point for ‘ReactJS Style guide ‘ . Thanks for the article
Cool! Thanks for the tips!
Nice article!
Link of “excellent documentation” is “http://http//facebook.github.io/react/docs/”.
Nice catch, fixed 🙂
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.
great, great article – so clear and concise
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)}
);
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.
@John Cobb – well, there’s the advantage that the ES6 version isn’t a deprecated version that the creator has said will be phased out completely in the future…
@Bryan You’ll notice that the article, and comment you’re replying to, were written over 18 months ago. While you are correct now and I wholeheartedly agree, at the time of writing the article ES6 React classes were not available at all, and if you take the time to look at the link in the comment above – they had just been introduced in a pre-release beta. However, I appreciate you taking the time to comment, albeit anonymously and with unnecessary condescension notwithstanding.
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.
Thanks! So precise and shows a proper direction to write react apps.
Great post. Thanks!
This is a great starting point to discuss React best practices.
I got this article recommended by a friend. Really appreciate you took the time to write this guide.
Great and well-written article. Thank you for this. Cheers!
Hi John Cobb, nice sharing, but if you are using es6/es2015, your code will look some what different.
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!
{ /* COMMENT */ }
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
Its a wonderful post. I like the information provided here.
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
Nice article, let me learn Reactjs a lot.
Great post! Exactly what I need to start using ReactJS.
Thanks!
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.
Do you have any conventions on how to name companents ?
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
}
https://github.com/airbnb/javascript/tree/master/react#methods
Do not use underscore prefix for internal methods of a React component.
^_^
Good one 🙂
Thanks for the write up, it’s helped me out a lot 🙂
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.
React.js Tips & Best Practices – http://www.toptal.com/react/tips-and-practices/#remote-developer-job
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?)
Useful article.
It is great to use React.js for my project. Thank you so much for your sharing.
Really useful article for beginners in react.Thanks for sharing.
Good article.thanks for making program very simple with easy tricks.
It is a very good article for beginners.Now I learn the react js.Thanks for posting the article.
Nice sharing John thanks !
I can’t understand the JSX concept in the ReactJS can you plz solve the problem
Regards,
John
ReactJS Developer
Agree with everything.
But in Conditional JSX I like to have the condition and the jsx directly in the return statement. I think it makes it easier to see what markup will be rendered.
return (
{this.props.conditional && (
…
)}
);
I lost the markup in the comment field cleanup process but I hope it makes sense
Very Good stuff,hard to find such cool tips
This website will really help everyone in providing the tools and information necessary for the people to develop and improve their website.
The content is good and very informative and I personally thank you for sharing React.js articles with us.
Thank you for the Good information which is very usefull