# Airbnb React/JSX Style Guide *A mostly reasonable approach to React and JSX* This style guide is mostly based on the standards that are currently prevalent in JavaScript, although some conventions (i.e async/await or static class fields) may still be included or prohibited on a case-by-case basis. Currently, anything prior to stage 3 is not included nor recommended in this guide. ## Table of Contents 1. [Basic Rules](#basic-rules) 1. [Class vs `React.createClass` vs stateless](#class-vs-reactcreateclass-vs-stateless) 1. [Mixins](#mixins) 1. [Naming](#naming) 1. [Declaration](#declaration) 1. [Alignment](#alignment) 1. [Quotes](#quotes) 1. [Spacing](#spacing) 1. [Props](#props) 1. [Refs](#refs) 1. [Parentheses](#parentheses) 1. [Tags](#tags) 1. [Methods](#methods) 1. [Ordering](#ordering) 1. [`isMounted`](#ismounted) ## Basic Rules - Only include one React component per file. - However, multiple [Stateless, or Pure, Components](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions) are allowed per file. eslint: [`react/no-multi-comp`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless). - Always use JSX syntax. - Do not use `React.createElement` unless you’re initializing the app from a file that is not JSX. - [`react/forbid-prop-types`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md) will allow `arrays` and `objects` only if it is explicitly noted what `array` and `object` contains, using `arrayOf`, `objectOf`, or `shape`. ## Class vs `React.createClass` vs stateless - If you have internal state and/or refs, prefer `class extends React.Component` over `React.createClass`. eslint: [`react/prefer-es6-class`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md) [`react/prefer-stateless-function`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md) ```jsx // bad const Listing = React.createClass({ // ... render() { return
{this.state.hello}
; } }); // good class Listing extends React.Component { // ... render() { return
{this.state.hello}
; } } ``` And if you don’t have state or refs, prefer normal functions (not arrow functions) over classes: ```jsx // bad class Listing extends React.Component { render() { return
{this.props.hello}
; } } // bad (relying on function name inference is discouraged) const Listing = ({ hello }) => (
{hello}
); // good function Listing({ hello }) { return
{hello}
; } ``` ## Mixins - [Do not use mixins](https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html). > Why? Mixins introduce implicit dependencies, cause name clashes, and cause snowballing complexity. Most use cases for mixins can be accomplished in better ways via components, higher-order components, or utility modules. ## Naming - **Extensions**: Use `.jsx` extension for React components. eslint: [`react/jsx-filename-extension`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md) - **Filename**: Use PascalCase for filenames. E.g., `ReservationCard.jsx`. - **Reference Naming**: Use PascalCase for React components and camelCase for their instances. eslint: [`react/jsx-pascal-case`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md) ```jsx // bad import reservationCard from './ReservationCard'; // good import ReservationCard from './ReservationCard'; // bad const ReservationItem = ; // good const reservationItem = ; ``` - **Component Naming**: Use the filename as the component name. For example, `ReservationCard.jsx` should have a reference name of `ReservationCard`. However, for root components of a directory, use `index.jsx` as the filename and use the directory name as the component name: ```jsx // bad import Footer from './Footer/Footer'; // bad import Footer from './Footer/index'; // good import Footer from './Footer'; ``` - **Higher-order Component Naming**: Use a composite of the higher-order component’s name and the passed-in component’s name as the `displayName` on the generated component. For example, the higher-order component `withFoo()`, when passed a component `Bar` should produce a component with a `displayName` of `withFoo(Bar)`. > Why? A component’s `displayName` may be used by developer tools or in error messages, and having a value that clearly expresses this relationship helps people understand what is happening. ```jsx // bad export default function withFoo(WrappedComponent) { return function WithFoo(props) { return ; } } // good export default function withFoo(WrappedComponent) { function WithFoo(props) { return ; } const wrappedComponentName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; WithFoo.displayName = `withFoo(${wrappedComponentName})`; return WithFoo; } ``` - **Props Naming**: Avoid using DOM component prop names for different purposes. > Why? People expect props like `style` and `className` to mean one specific thing. Varying this API for a subset of your app makes the code less readable and less maintainable, and may cause bugs. ```jsx // bad // bad // good ``` ## Declaration - Do not use `displayName` for naming components. Instead, name the component by reference. ```jsx // bad export default React.createClass({ displayName: 'ReservationCard', // stuff goes here }); // good export default class ReservationCard extends React.Component { } ``` ## Alignment - Follow these alignment styles for JSX syntax. eslint: [`react/jsx-closing-bracket-location`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md) [`react/jsx-closing-tag-location`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md) ```jsx // bad // good // if props fit in one line then keep it on the same line // children get indented normally // bad {showButton &&