Skip to content

Latest commit

 

History

History
executable file
·
448 lines (334 loc) · 11 KB

README.md

File metadata and controls

executable file
·
448 lines (334 loc) · 11 KB

React

Saiku React code styleguide.

Table of Contents

  1. Basic Rules
  2. Class vs React.createClass vs stateless
  3. Naming
  4. Declaration
  5. Alignment
  6. Quotes
  7. Spacing
  8. Props
  9. Parentheses
  10. Tags
  11. Methods
  12. Ordering
  13. isMounted
  14. Resources

Basic Rules

⬆ back to top

Class vs React.createClass vs stateless

// 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>;
  }
}

And if you don't have state or refs, prefer normal functions (not arrow functions) over classes:

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

// Bad (since arrow functions do not have a "name" property)
const Listing = ({ hello }) => (
  <div>{hello}</div>
);

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

⬆ back to top

Naming

  • 3.1 Extensions: Use .jsx extension for React components.
  • 3.2 Filename: Use PascalCase for filenames. E.g., ReservationCard.jsx.
  • 3.1 Reference Naming: Use PascalCase for React components and camelCase for their instances. eslint: react/jsx-pascal-case
// Bad
import reservationCard from './ReservationCard';

// Good
import ReservationCard from './ReservationCard';

// Bad
const ReservationItem = <ReservationCard />;

// Good
const reservationItem = <ReservationCard />;
  • 3.4 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:
// Bad
import Footer from './Footer/Footer';

// Bad
import Footer from './Footer/index';

// Good
import Footer from './Footer';

⬆ back to top

Declaration

  • 4.1 Do not use displayName for naming components. Instead, name the component by reference.
// Bad
export default React.createClass({
  displayName: 'ReservationCard',
  // stuff goes here
});

// Good
export default class ReservationCard extends React.Component {
}

⬆ back to top

Alignment

// Bad
<Foo superLongParam="bar"
     anotherSuperLongParam="baz" />

// Good
<Foo
  superLongParam="bar"
  anotherSuperLongParam="baz"
/>

// if props fit in one line then keep it on the same line
<Foo bar="bar" />

// children get indented normally
<Foo
  superLongParam="bar"
  anotherSuperLongParam="baz"
>
  <Quux />
</Foo>

⬆ back to top

Quotes

  • 6.1 Always use double quotes (") for JSX attributes, but single quotes for all other JS. eslint: jsx-quotes

Why? JSX attributes can't contain escaped quotes, so double quotes make conjunctions 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={{ left: "20px" }} />

// Good
<Foo style={{ left: '20px' }} />

⬆ back to top

Spacing

  • 7.1 Always include a single space in your self-closing tag.
// Bad
<Foo/>

// Very bad
<Foo                 />

// Bad
<Foo
 />

// Good
<Foo />

⬆ back to top

Props

  • 8.1 Always use camelCase for prop names.
// Bad
<Foo
  UserName="hello"
  phone_number={12345678}
/>

// Good
<Foo
  userName="hello"
  phoneNumber={12345678}
/>
// Bad
<Foo
  hidden={true}
/>

// Good
<Foo
  hidden
/>

⬆ back to top

Parentheses

// 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>;
}

⬆ back to top

Tags

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

// Good
<Foo className="stuff" />
// Bad
<Foo
  bar="bar"
  baz="baz" />

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

⬆ back to top

Methods

Why? A bind call in the render path creates a brand new function on every single render.

// Bad
class extends React.Component {
  onClickDiv() {
    // do stuff
  }

  render() {
    return <div onClick={this.onClickDiv.bind(this)} />
  }
}

// Good
class extends React.Component {
  constructor(props) {
    super(props);

    this.onClickDiv = this.onClickDiv.bind(this);
  }

  onClickDiv() {
    // do stuff
  }

  render() {
    return <div onClick={this.onClickDiv} />
  }
}
  • 11.2 Do not use underscore prefix for internal methods of a React component.
// Bad
React.createClass({
  _onClickSubmit() {
    // do stuff
  },

  // other stuff
});

// Good
class extends React.Component {
  onClickSubmit() {
    // do stuff
  }

  // other stuff
}

⬆ back to top

Ordering

  • 12.1 Ordering for class extends React.Component:
  1. optional static methods
  2. constructor
  3. getChildContext
  4. componentWillMount
  5. componentDidMount
  6. componentWillReceiveProps
  7. shouldComponentUpdate
  8. componentWillUpdate
  9. componentDidUpdate
  10. componentWillUnmount
  11. clickHandlers or eventHandlers like onClickSubmit() or onChangeDescription()
  12. getter methods for render like getSelectReason() or getFooterContent()
  13. Optional render methods like renderNavigation() or renderProfilePicture()
  14. render
  • 12.2 How to define propTypes, defaultProps, contextTypes, etc...
import React, { PropTypes } from 'react';

const propTypes = {
  id: PropTypes.number.isRequired,
  url: PropTypes.string.isRequired,
  text: PropTypes.string,
};

const defaultProps = {
  text: 'Hello World',
};

class Link extends React.Component {
  static methodsAreOk() {
    return true;
  }

  render() {
    return <a href={this.props.url} data-id={this.props.id}>{this.props.text}</a>
  }
}

Link.propTypes = propTypes;
Link.defaultProps = defaultProps;

export default Link;
  1. displayName
  2. propTypes
  3. contextTypes
  4. childContextTypes
  5. mixins
  6. statics
  7. defaultProps
  8. getDefaultProps
  9. getInitialState
  10. getChildContext
  11. componentWillMount
  12. componentDidMount
  13. componentWillReceiveProps
  14. shouldComponentUpdate
  15. componentWillUpdate
  16. componentDidUpdate
  17. componentWillUnmount
  18. clickHandlers or eventHandlers like onClickSubmit() or onChangeDescription()
  19. getter methods for render like getSelectReason() or getFooterContent()
  20. Optional render methods like renderNavigation() or renderProfilePicture()
  21. render

⬆ back to top

isMounted

Why? isMounted is an anti-pattern, is not available when using ES6 classes, and is on its way to being officially deprecated.

⬆ back to top

Resources

Inspiration

⬅ back to main    ⬆ back to top