React/JSX Style Guide

A mostly reasonable approach to React and JSX Edit

Table of Contents

  1. Class vs React.createClass vs stateless
  2. Quotes
  3. Props
  4. Refs
  5. Parentheses
  6. Tags

Class vs React.createClass vs stateless

If you have internal state and/or refs, prefer class extends React.Component over React.createClass unless you have a very good reason to use mixins 1, 2.

// bad
const Listing = React.createClass({
  // ...
  render() {
    return <div>{this.state.hello}</div>;
  }
});

// good
class Listing extends React.Component {
  // ...
  render() {
    return <div>{this.state.hello}</div>;
  }
}

If you don’t have state or refs, prefer normal functions (not arrow functions) over classes. When debugging in the good example below the stack trace will include the function name whereas in the bad example it will say it’s from an anonymous function:

// bad
class Listing extends React.Component {
  render() {
    return <div>{this.props.hello}</div>;
  }
}

// bad (relying on function name inference is discouraged)
const Listing = ({ hello }) => (
  <div>{hello}</div>
);

// good
function Listing({ hello }) {
  return <div>{hello}</div>;
}

Quotes

Always use double quotes (") for JSX attributes, and single quotes for all other JS 3. JSX attributes can’t contain escaped quotes, so double quotes make contractions like "don't" easier to type. Regular HTML attributes also typically use double quotes instead of single, so JSX attributes mirror this convention:

// bad
<Foo bar='bar' />

// good
<Foo bar="bar" />

// bad
<Foo style= />

// good
<Foo style= />

Props

Always use camelCase for prop names.

// bad
<Foo
  UserName="hello"
  phone_number={12345678}
/>

// good
<Foo
  userName="hello"
  phoneNumber={12345678}
/>

Omit the value of the prop when it is explicitly true. 4

// bad
<Foo
  hidden={true}
/>

// good
<Foo
  hidden
/>

Avoid using an array index as key prop, prefer a unique ID; using the index as a key is an anti-pattern.

// bad
{todos.map((todo, index) =>
  <Todo
    {...todo}
    key={index}
  />
)}

// good
{todos.map(todo => (
  <Todo
    {...todo}
    key={todo.id}
  />
))}

Refs

Always use ref callbacks 5.

// bad
<Foo
  ref="myRef"
/>

// good
<Foo
  ref={ref => { this.myRef = ref; }}
/>

Parentheses

Wrap JSX tags in parentheses when they span more than one line 6.

// bad
render() {
  return <MyComponent className="long body" foo="bar">
           <MyChild />
         </MyComponent>;
}

// good
render() {
  return (
    <MyComponent className="long body" foo="bar">
      <MyChild />
    </MyComponent>
  );
}

// good, when single line
render() {
  const body = <div>hello</div>;
  return <MyComponent>{body}</MyComponent>;
}

Tags

Always self-close tags that have no children 7.

// bad
<Foo className="stuff"></Foo>

// good
<Foo className="stuff" />

If your component has multi-line properties, close its tag on a new line 8.

Why? It produces nicer diffs.

// bad
<Foo
  bar="bar"
  baz="baz" />

// good
<Foo
  bar="bar"
  baz="baz"
/>