React Style Guide

(Based on Khan Academy’s style guide)

Follow the normal JavaScript style guide - including the 80 character line limit. In addition, there are several React-specific rules.

In addition to these style rules, you may also be interested in React best practices.


Use semantic HTML5.

Although it is tempting to add all functionality to DIVs, keep in mind that the HTML5 you are writing with React must be semantically meaningful and validating. Only put an onClick action on a native focusable element, like a <button>.

// Bad:
render() {
    return <div onClick={ () => this.props.onClick() }>
        { /* ... */ }

// Good:
render() {
    return <button
        onClick={ e => { e.preventDefault(); this.props.onClick() } }
        { /* ... */ }

Use ES6 class components.

Never use ES5-style React.createClass. Your components should always be full ES6 subclasses of React.Component:

import React from 'react';

export default class MyComponent extends React.Component {
	render() {
		return <div />;

Even when using export default, include a class name to allow easier debugging with the React tooling.

This also requires setting static properties on the class; in particular, getDefaultProps becomes MyComponent.defaultProps and getInitialState is added to the constructor:

// Old:
const MyComponent = React.createClass({
	getDefaultProps: function () {
		return { some: 'props' };
	getInitialState: function () {
		return { some: 'state' };

// New:
export default class MyComponent extends React.Component {
	constructor(props) {
		this.state = { some: 'state' };

MyComponent.defaultProps = { some: 'props' };
Functional or Class components

Components can be declared both as classes and as functions. Here’s a sample of a functional component:

export default function MyComponent( props ) {
	return <div>
	    { props.text }

This component is easier to read but there are no advantages to use this in terms of performance.

You can use functional components for small and simple components that don’t need the full functionality offered by class components, like:

  • State for the component
  • Lifecycle hooks
  • Include performance optimizations
  • Make use of refs. They are not supported in React 16 for functional components.
  • To extend from PureComponent

Order your methods with lifecycle first and render last.

Within your react component, you should order your methods like so:

  1. lifecycle methods, in chronological order:
    • componentWillMount
    • componentDidMount
    • componentWillReceiveProps
    • shouldComponentUpdate
    • componentWillUpdate
    • componentDidUpdate
    • componentWillUnmount
  2. everything else
  3. render

Name handlers onEventName.


<Component onClick={ e => this.onClick( e ) } onLaunchMissiles={ num => this.onLaunchMissiles( num ) } />

Name handlers props onEventName.

This is consistent with React’s event naming: onClick, onDrag, onChange, etc.


Component.propTypes = {
	onLaunchMissiles: React.PropTypes.func.isRequired,
	onScram: React.PropTypes.func.isRequired,

Open elements on the same line.

The 80-character line limit is a bit tight, so we opt to conserve the extra 4.


return <div>


return (      // "div" is not on the same line as "return"

Align and sort HTML properties.

Fit them all on the same line if you can. If you can’t, put each property on a line of its own, indented one tab, in sorted order. The closing angle brace should be on a line of its own, indented the same as the opening angle brace. This makes it easy to see the props at a glance.

When sorting properties, sort alphabetically in the following groups:

  • key should be first if required.
  • Values
  • Event handlers (on...)


<div className="highlight" key="highlight-div">
    onClick={ () => this.onClick() }


<div className="highlight"      // property not on its own line
<div                            // closing brace not on its own line
<div                            // property is not sorted
<Image                          // handlers should be after values
	onClick={ () => this.onClick() }

Only export a single react class.

Every .js file should export a single React class, and nothing else. This is for testability; the fixture framework requires it to function.

Note that the file can still define multiple classes, it just can’t export more than one.

Language features

Make “presentation” components pure.

It’s useful to think of the React world as divided into “logic” components and “presentation” components.

“Logic” components have application logic, but do not emit HTML themselves.

“Presentation” components are typically reusable, and do emit HTML.

Logic components can have internal state, but presentation components never should.

Prefer props to state.

You almost always want to use props. By avoiding state when possible, you minimize redundancy, making it easier to reason about your application.

A common pattern — which matches the “logic” vs. “presentation” component distinction — is to create several stateless components that just render data, and have a stateful component above them in the hierarchy that passes its state to its children via props. The stateful component encapsulates all of the interaction logic, while the stateless components take care of rendering data in a declarative way.

Copying data from props to state can cause the UI to get out of sync and is especially bad.

Use propTypes.

React Components should always have complete propTypes. Every attribute of this.props should have a corresponding entry in propTypes. This documents that props need to be passed to a model. (example)

If you are passing data through to a child component, you can use the prop-type <child-class>.propTypes.<prop-name>.

Avoid these non-descriptive prop-types:

  • React.PropTypes.any
  • React.PropTypes.array
  • React.PropTypes.object

Instead, use

  • React.PropTypes.arrayOf
  • React.PropTypes.objectOf
  • React.PropTypes.instanceOf
  • React.PropTypes.shape

As an exception, if you are passing data through to a child component, and you can’t use <child-class>.propTypes.<prop-name> for some reason, you can use React.PropType.any.

Never store state in the DOM.

Do not use data- attributes or classes. All information should be stored in JavaScript, either in the React component itself, or in a React store if using a framework such as Redux.

Libraries and components

Do not use Backbone models.

Use Redux actions, or fetch() directly instead.

Avoid Underscore.

Most functionality offered by Underscore is available natively in ES6 with minimal changes required. Where possible, use the native functionality.

If you need Underscore functionality, consider using Lodash instead. Lodash allows importing singular functions, providing only the functionality you need:

import map from 'lodash/map';

Minimize use of jQuery.

Never use jQuery for DOM manipulation.

Try to avoid using jQuery plugins. When necessary, wrap the jQuery plugin with a React component so you only have to touch the jQuery once.

For Ajax, the native fetch() API (with polyfill) should be used instead of $.ajax.