Uma abordagem para padronização de códigos usada pela AirBNB React e JSX, traducão feita com base nesse repositório
- Regras Básicas
- Class vs
React.createClassvs stateless - Nomenclatura
- Declaration
- Indentação
- Aspas
- Espaçamento
- Props
- Refs
- Parenteses
- Tags
- Métodos (Methods)
- Prioridades
isMounted
-
Apenas um componente por arquivo.
- Contudo, múltiplos componentes são permitidos quando são dependentes um do outro e apenas 1 tem retorno Statefull ou Stateless são permitidos por arquivo. eslint:
react/no-multi-comp.
function Hello(props) { return <div>Hello {props.name}</div>; } class HelloJohn extends React.Component { render() { return <Hello name="John" />; } } module.exports = HelloJohn;
- Contudo, múltiplos componentes são permitidos quando são dependentes um do outro e apenas 1 tem retorno Statefull ou Stateless são permitidos por arquivo. eslint:
-
Sempre use a sintaxe JSX.
-
Não use
React.createElementa não ser que você estaja declarando a partir de um arquivo que não seja JSX.
-
Se você tem State interno e/ou refs, opte por
class extends React.Componentao invés deReact.createClassa menos que você tenha uma boa razão para usar um mixins. eslint:react/prefer-es6-classreact/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
stateourefs, 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>; }
-
Extensão: Use a extensão
.jsxpara 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.jsxtem um nome que referênciaMeuComponente. No entanto, para os componentes de raiz de um diretório, useindex.jsxcomo 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';
-
Não use
displayNamepara 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 }
-
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>
- 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' }} />
```
-
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} />
-
Sempre use
camelCasepara prop names.// ruim <Componente UserName="hello" phone_number={12345678} /> // ideal <Componente userName="hello" phoneNumber={12345678} />
-
Quando o valor Booleano for
truepode ser omitido. eslint:react/jsx-boolean-value// ruim <Component hidden={true} /> // ideal <Component hidden />
-
Sempre inclua o parâmetro
altem suas<img>tags. Ealtpode 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
altde sua<img>. eslint:jsx-a11y/img-redundant-alt
Sério? Screenreaders já interpretam
imgcomo 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
accessKeyem 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
indexcomokeyde 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}
/>
))}-
Sempre use
ref callbacks. eslint:react/no-string-refs// ruim <Foo ref="myRef" /> // ideal <Foo ref={(ref) => this.myRef = ref} />
-
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>; }
-
Sempre que a Tag não possuir
childrenuse 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" />
-
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 para
class extends React.Component:
- opcional
static constructorgetChildContextcomponentWillMountcomponentDidMountcomponentWillReceivePropsshouldComponentUpdatecomponentWillUpdatecomponentDidUpdatecomponentWillUnmount- clickHandlers ou eventHandlers tipo
onClickSubmit()ouonChangeDescription() - getter methods para o
rendertipogetSelectReason()ougetFooterContent() - Métodos opcionais de render tipo
renderNavigation()ourenderProfilePicture() 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
displayNamepropTypescontextTypeschildContextTypesmixinsstaticsdefaultPropsgetDefaultPropsgetInitialStategetChildContextcomponentWillMountcomponentDidMountcomponentWillReceivePropsshouldComponentUpdatecomponentWillUpdatecomponentDidUpdatecomponentWillUnmount- clickHandlers ou eventHandlers tipo
onClickSubmit()ouonChangeDescription() - getter methods for
rendertipogetSelectReason()ougetFooterContent() - Optional render methods tipo
renderNavigation()ourenderProfilePicture() render
- Não use
isMounted. eslint:react/no-is-mounted
Sério?
isMountedé um anti-pattern, não estára mais disponível nas classes ES6 (ECMA2015), e está a caminho de ser oficialmentedeprecated(descontinuado).
This JSX/React style guide is also available in other languages:
Chinese (Simplified): JasonBoy/javascript
Polish: pietraszekl/javascript
Korean: apple77y/javascript
Brazilian: ronal2do/javascript