Skip to content

Latest commit

 

History

History
579 lines (445 loc) · 16.1 KB

README.md

File metadata and controls

579 lines (445 loc) · 16.1 KB

Airbnb React/JSX Style Guide

Uma abordagem para padronização de códigos usada pela AirBNB React e JSX, traducão feita com base nesse repositório

Índice

  1. Regras Básicas
  2. Class vs React.createClass vs stateless
  3. Nomenclatura
  4. Declaration
  5. Indentação
  6. Aspas
  7. Espaçamento
  8. Props
  9. Refs
  10. Parenteses
  11. Tags
  12. Métodos (Methods)
  13. Prioridades
  14. isMounted

Regras Básicas

  • Apenas um componente por arquivo.

    function Hello(props) {
      return <div>Hello {props.name}</div>;
    }
    class HelloJohn extends React.Component {
      render() {
        return <Hello name="John" />;
      }
    }
    module.exports = HelloJohn;
  • Sempre use a sintaxe JSX.

  • Não use React.createElement a não ser que você estaja declarando a partir de um arquivo que não seja JSX.

Class vs React.createClass vs stateless

  • Se você tem State interno e/ou refs, opte por class extends React.Component ao invés de React.createClass a menos que você tenha uma boa razão para usar um mixins. eslint: react/prefer-es6-class react/prefer-stateless-function

    // ruim
    const Listing = React.createClass({
      // ...
      render() {
        return <div>{this.state.hello}</div>;
      }
    });
    
    // ideal
    class Listing extends React.Component {
      // ...
      render() {
        return <div>{this.state.hello}</div>;
      }
    }

    E se você não tem state ou refs , prefira funções normais ( não arrow functions ) sobre as classes:

    // ruim
    class Listing extends React.Component {
      render() {
        return <div>{this.props.hello}</div>;
      }
    }
    
    // ruim (relying on function name inference is discouraged)
    const Listing = ({ hello }) => (
      <div>{hello}</div>
    );
    
    // ideal
    function Listing({ hello }) {
      return <div>{hello}</div>;
    }

Nomenclatura

  • Extensão: Use a extensão .jsx para componentes React.

  • Nome do arquivo: Use PascalCase para os arquivos. Ex.: MeuComponente.jsx.

  • Referência de nomenclatura: Use PascalCase para componentes e camelCase para as instâncias. eslint: react/jsx-pascal-case

    // ruim
    import reservationCard from './ReservationCard';
    
    // ideal
    import ReservationCard from './ReservationCard';
    
    // ruim
    const ReservationItem = <ReservationCard />;
    
    // ideal
    const reservationItem = <ReservationCard />; //instância em camel e componente em Pascal
  • Nomeando componentes: Use o mesmo nome do componente. Ex.: MeuComponente.jsx tem um nome que referência MeuComponente. No entanto, para os componentes de raiz de um diretório, use index.jsx como o nome do arquivo e usar o nome de diretório como o nome do componente:

  • App
    ├─┬ Footer
    │ ├── index.jsx (O componente Footer está declarado na index)
    │ ├── MeuComponente.jsx

    ├─┬ Header
    │ ├── index.jsx (O componente Header está declarado na index)
    │ │
    │ ├─┬ Meta
    │ │ ├── index.jsx (O componente Meta está declarado na index)
    │ │
    │ ├─┬ Menu.jsx
    │ │ ├── index.jsx
    │ │ ├── Item.jsx

    // ruim
    import Footer from './Footer/Footer';
    
    // ruim
    import Footer from './Footer/index';
    
    // ideal
    import Footer from './Footer';

Declaração

  • Não use displayName para nomear componentes. Em vez disso, o nome do componente por referência.

    // ruim
    export default React.createClass({
      displayName: 'MeuComponente',
      // alguma coisa aqui.
    });
    
    // ideal
    export default class MeuComponente extends React.Component {
      // todo 
    }

Indentação

  • Siga estes estilos de indentação para sintaxe JSX. eslint: react/jsx-closing-bracket-location

    // ruim
    <Componente primeiroParametro="bar"
                maisUmParametro="baz" />
    
    // ideal
    <Componente
      primeiroParametro="bar"
      maisUmParametro="baz"
    />
    
    // Se for apenas um parâmetro coloque na mesma linha.
    <Componente bar="bar" />
    
    // children recebe indentação normal.
    <Componente
      primeiroParametro="bar"
      maisUmParametro="baz"
    >
      <ComponenteFilho />
    </Componente>

Aspas

  • Sempre usa aspas duplas (") para atributos, mas aspas simples para todos os outros JS usados no componente. eslint: jsx-quotes

Sério? Atributos JSX can't contain escaped quotes, assim aspas fazem conjunções como "Don't" tornando-se mais fáceis de digitar. atributos regulares HTML também costumam usar aspas duplas em vez de únicas, de modo atributos JSX espelhão esta convenção.

```jsx
// ruim
<Componente bar='bar' />

// ideal
<Componente bar="bar" />

// ruim
<Componente style={{ left: "20px" }} />

// ideal
<Componente style={{ left: '20px' }} />
```

Espaçamento

  • Sempre inclua um único espaço no fechamento de suas tags que não recebem childrens.

    // ruim
    <Foo/>
    
    // tá de sacanagem néh?
    <Foo                 />
    
    // ruim
    <Foo
     />
    
    // ideal
    <Foo />
  • Não precisa usar espaço dentro nas chaves de parâmetros de um componente. eslint: react/jsx-curly-spacing

    // ruim
    <Foo bar={ baz } />
    
    // ideal
    <Foo bar={baz} />

Props

  • Sempre use camelCase para prop names.

    // ruim
    <Componente
      UserName="hello"
      phone_number={12345678}
    />
    
    // ideal
    <Componente
      userName="hello"
      phoneNumber={12345678}
    />
  • Quando o valor Booleano for true pode ser omitido. eslint: react/jsx-boolean-value

    // ruim
    <Component
      hidden={true}
    />
    
    // ideal
    <Component
      hidden
    />
  • Sempre inclua o parâmetro alt em suas <img> tags. E alt pode ser uma string vazia em <img> . eslint: jsx-a11y/img-has-alt

    // ruim
    <img src="hello.jpg" />
    
    // ideal
    <img src="hello.jpg" alt="Me waving hello" />
    
    // ideal
    <img src="hello.jpg" alt="" />
  • Não use palavras como "image", "photo", ou "picture" no alt de sua <img> . eslint: jsx-a11y/img-redundant-alt

Sério? Screenreaders já interpretam img como um elemento de imagem, por isso não há necessidade de incluir esta informação no texto do alt.

```jsx
// ruim
<img src="hello.jpg" alt="Picture of me waving hello" />

// ideal
<img src="hello.jpg" alt="Me waving hello" />
```
  • Use apenas válido, não- abstrato ARIA roles. eslint: jsx-a11y/aria-role

    // ruim - não é uma ARIA role
    <div role="datepicker" />
    
    // ruim - abstrata ARIA role
    <div role="range" />
    
    // ideal
    <div role="button" />
  • Não use accessKey em seus elementos. eslint: jsx-a11y/no-access-key

Sério? Inconsistências entre os atalhos de teclado e comandos de teclado usados ​​por pessoas que usam leitores de tela e teclados podem complicar a acessibilidade.

// ruim
<div accessKey="h" />

// ideal
<div />
  • Evite usar index como key de props, opte por um ID. (Sério?)
// ruim
{todos.map((todo, index) =>
  <Todo
    {...todo}
    key={index}
  />
)}

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

Refs

  • Sempre use ref callbacks. eslint: react/no-string-refs

    // ruim
    <Foo
      ref="myRef"
    />
    
    // ideal
    <Foo
      ref={(ref) => this.myRef = ref}
    />

Parenteses

  • Coloque Tags JSX entre parênteses quando eles abrangem mais de uma linha. eslint: react/wrap-multilines

    // ruim
    render() {
      return <Componente className="long body" foo="bar">
               <ComponenteFilho />
             </Componente>;
    }
    
    // ideal
    render() {
      return (
        <Componente className="long body" foo="bar">
          <ComponenteFilho />
        </Componente>
      );
    }
    
    // ideal, para uma linha.
    render() {
      const body = <div>hello</div>;
      return <Componente>{body}</Componente>;
    }

Tags

  • Sempre que a Tag não possuir children use self-close ( ). eslint: react/self-closing-comp

    // ruim
    <Foo className="stuff"></Foo>
    
    // ideal
    <Foo className="stuff" />
  • Se o seu componente tiver mais de uma linha de propriedades(props), feche a Tag em uma nova linha. eslint: react/jsx-closing-bracket-location

    // ruim
    <Foo
      bar="bar"
      baz="baz" />
    
    // ideal
    <Foo
      bar="bar"
      baz="baz"
    />

Métodos (Methods)

  • Use arrow functions para variáveis locais.

    function ItemList(props) {
      return (
        <ul>
          {props.items.map((item, index) => (
            <Item
              key={item.key}
              onClick={() => fazerAlgoCom(item.name, index)}
            />
          ))}
        </ul>
      );
    }
  • Manipuladores de evento do método render dentro do constructor() eslint: react/jsx-no-bind

    // ruim
    class extends React.Component {
      onClickDiv() {
        // do stuff
      }
    
      render() {
        return <div onClick={this.onClickDiv.bind(this)} />
      }
    }
    
    // ideal
    class extends React.Component {
      constructor(props) {
        super(props);
    
        this.onClickDiv = this.onClickDiv.bind(this);
      }
    
      onClickDiv() {
        // do stuff
      }
    
      render() {
        return <div onClick={this.onClickDiv} />
      }
    }
  • Não use underscore prefix para métodos internos de um componente React.

    // ruim
    React.createClass({
      _onClickSubmit() {
        // do stuff
      },
    
      // other stuff
    });
    
    // ideal
    class extends React.Component {
      onClickSubmit() {
        // do stuff
      }
    
      // other stuff
    }
  • Certifique-se de retornar um valor em seu método render. eslint: require-render-return

    // ruim
    render() {
      (<div />);
    }
    
    // ideal
    render() {
      return (<div />);
    }

Prioridades

  • Prioridades para class extends React.Component:
  1. opcional static
  2. constructor
  3. getChildContext
  4. componentWillMount
  5. componentDidMount
  6. componentWillReceiveProps
  7. shouldComponentUpdate
  8. componentWillUpdate
  9. componentDidUpdate
  10. componentWillUnmount
  11. clickHandlers ou eventHandlers tipo onClickSubmit() ou onChangeDescription()
  12. getter methods para o render tipo getSelectReason() ou getFooterContent()
  13. Métodos opcionais de render tipo renderNavigation() ou renderProfilePicture()
  14. render
  • Como definir 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;
  • Prioridades para React.createClass: eslint: react/sort-comp

  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 ou eventHandlers tipo onClickSubmit() ou onChangeDescription()
  19. getter methods for render tipo getSelectReason() ou getFooterContent()
  20. Optional render methods tipo renderNavigation() ou renderProfilePicture()
  21. render

isMounted

Sério? isMounted é um anti-pattern, não estára mais disponível nas classes ES6 (ECMA2015), e está a caminho de ser oficialmente deprecated (descontinuado).

Translation

This JSX/React style guide is also available in other languages:

⬆ back to top