1.0.7 • Published 6 years ago

eslint-config-zup-react v1.0.7

Weekly downloads
12
License
MIT
Repository
-
Last release
6 years ago

Zup - Style Guide

Os padrões que iremos adotar para serem utilizados em nossos projetos.

Indice

React and Javascript Style Guide

Este guia foi criado para mantermos o estilo de código React que adotamos aqui na Zup, e algumas práticas que nós consideramos ser adequadas. Nosso estilo é baseado no Airbnb com algumas modificações.

Objetivo

Qual o propósito de utilizarmos um Style Guide? O principal objectivo é mantermos uma única forma de escrita, porém também ganhamos:

  • Melhor Legibilidade de código
  • Melhor manutenção do código
  • Ganho de tempo em code reviews
  • Padrão de desenvolvimento
  • Boas práticas de programação
  • Clean Code
  • Entre outros grandes benefícios

Instalação

yarn add --dev eslint@4.19.1 eslint-config-zup-react

Crie um arquivo .eslintrc.js na pasta raiz do seu projeto com o seguinte conteúdo:

module.exports = {
  "extends": "zup-react"
}

Rules

Extensão de componentes React

  • Ao criar um arquivo React sempre utilize a extensão .jsx
Button/
├── index.jsx

Criação de componentes com folha de estilo

  • Quando necessário criar um componente que terá estilos, sempre opte por styled-components e com a seguinte estrutura:
Button/
├── index.jsx
└── styled.js

Importando Component

  • Sempre que for extender uma classe com Component ou PureComponent faça a destruturação na importação.
// Bad
import React from 'react'
class Classe extends React.Component

// Good
import React, { Component } from 'react'
class Classe extends Component

Criação de Classes

// Very Bad
import React from 'react'
const Classe = React.createClass({
  render() {
    ....
  }
})

// Bad
import React from 'react'
class Classe extends React.Component {
  render() {
    ....
  }
}

// Good
import React, { Component } from 'react'
class Classe extends Component {
  render() {
    ....
  }
}

Stateless Component

  • Prefira utilizar a sintaxe funcional para componentes sem estado e em dumb components.
const Title = (props) => (
  <h1>{props.title}</h1>
)

Stateful Component

  • Prefira utilizar a sintaxe de classes para componentes que possuem conhecimento do estado, em container e componentes que utilizem lifecycles.
class Title extends Component {
  render () {
    return (
      ....
    )
  }
}

State

  • Caso seja necessário criar um estado local na sua classe utilize a seguinte abordagem:
// Bad
class Example extends Component {
  componentWillMount() {
    this.state = {
      loading: true
    }
  }
}

// God
class Example extends Component {
  constructor() {
    super()
    this.state = {
      loading: true
    }
  }
}

// Best
class Example extends Component {
  state = {
    loading: true
  }
}

Adição de vírgula no último elemento de um objeto

  • Na utilização de objetos, sempre adicione vírgula no último element, isso irá auxiliar na visualização do git diff, caso haja adição de um novo elemento na última posição.
// Bad
export {
  Provider,
  Consumer
}

// Good
export {
  Provider,
  Consumer,
}

Arrow function

  • Sempre prefira escrever funções com arrow functions, principalmente se o retorno couber apenas em uma linha, e quando houver callbacks com funções anônimas.
// Very Bad
function double(array) {
  return array.map(function(item) {
    return item * 2
  })
}

// Good
function double(array) {
  return array.map(item => item * 2)
}

// Best
const double = array => array.map(item => item * 2)

Setando uma variável

  • Sempre que possível, utilize const na inicialização de qualquer variável.
// Bad
var a = 1

// Good
const a = 1

Template Strings

  • Dê preferência ao uso de template strings na concatenação de strings.
// Bad
const person = {
  name: 'Isac'
}
const myName = "My name is "+ person.name+"."

// God
const person = {
  name: 'Isac'
}
const myName = `My name is ${person.name}.`

Ponto e vírgula

// Bad
import React from 'react';

// Good
import React from 'react'

Console.log

  • Nunca deixe console.log() em seu código
// Bad
const sum = (a, b) => {
  const result = a + b
  console.log(result)
}

Comentários

  • Nunca deixa comentários em seu código
// Bad
// Função que soma dois elementos
const sum = (a, b) => a + b

// Good
const sum = (a, b) => a + b

Retorno de elementos com JSX

  • Sempre que possível, omita o return
// Bad
const Bonus = () => {
  return (
    <div>
      <h1>Zup Style Guide</h1>
    </div>
  )
}

// Good
const Bonus = () => (
  <div>
    <h1>Zup Style Guide</h1>
  </div>
)

Destruturação de objetos

  • Sempre que possível, utilize destruturação de objetos
// Bad
const Title = (props) => (
  <h1>{props.title}</h1>
)

// Good
const Title = ({ title }) => (
  <h1>{title}</h1>
)

Exportação default

  • Caso o seu arquivo contenha somente um elemento a ser exportado, utilize export default
class ClasseNameA extends Component {
  render() {
    ....
  }
}

export default ClasseNameA

Englobar elementos em JSX

  • Sempre que retornar um elemento JSX, envolva em um elemento pai. Caso esteja utilizando versão superior a React 16.2, prefira Fragment, ou sintaxe curta de Fragment.
// Bad
import React from 'react'

const NameA = () => (
  <div>
    ....
  </div>
)

// Good
import React, { Fragment } from 'react'

const NameA = () => (
  <Fragment>
    ....
  </Fragment>
)

// Best
import React, { Fragment } from 'react'

const NameA = () => (
  <>
    ....
  </>
)

Transferindo props

  • Caso haja a necessidade de repassar props para outros componentes, defina-as e utilize nomes semânticos, ao invés de utilizar spread. Isso irá facilitar o entendimento do fluxo, e quais props estão sendo utilizadas. Evitando a passagem desnecessárias de outras.
// Bad
const Button = props => (
  <StyledButton {...props}>
    {props.children}
  </StyledButton>
)

// Good
const Button = ({ primary, children }) => (
  <StyledButton color={primary}>
    {children}
  </StyledButton>
)

Bind em métodos

  • Caso esteja sendo necessário criar bind para o contexto this, prefira utilizar métodos com arrow function.
// Bad
class MyComponent extends Component {
  constructor() {
    super()
    this.methodA = this.methodA.bind(this)
  }

  methodA() { ... }
}

// Good
class MyComponent extends Component {
  methodA = () => { ... }
}

Inicializando State

  • React > 16.3: Não utilize componentWillMount para iniciar o seu state
// Bad
class MyComponent extends Component {
  componentWillMount() {
    this.setState({
      currentColor: this.props.defaultColor,
      palette: 'rgb'
    })
  }
}

// Good
class MyComponent extends Component {
  state = {
    currentColor: this.props.defaultColor,
    palette: 'rgb'
  }
}

ComponentWillMount

  • React > 16.3: Sempre prefira o uso do componetDidMount ao invez do componentWillMount, o mesmo será descontinuado na versão 17.
// Bad
class MyComponent extends Component {
  componentWillMount() {
    ...
  }
}
// Good
class MyComponent extends Component {
  componentDidMount() {
    ...
  }
}

ComponentWillReceiveProps

  • React > 16.3: Este é um exemplo de verificação de props para atualização do estado. Sempre que se deparar com tal situação, utilize getDerivedStateFromProps para realizar tal operação. ComponentWillReceiveProps será descontinuado na versão 17.
// Bad
class ExampleComponent extends Component {
  state = {
    isScrollingDown: false
  };

  componentWillReceiveProps(nextProps) {
    if (this.props.currentRow !== nextProps.currentRow) {
      this.setState({
        isScrollingDown:
          nextProps.currentRow > this.props.currentRow
      })
    }
  }
}

// Good
class ExampleComponent extends Component {
  state = {
    isScrollingDown: false,
    lastRow: null
  }

  getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.currentRow !== prevState.lastRow) {
      return {
        isScrollingDown:
          nextProps.currentRow > prevState.lastRow,
        lastRow: nextProps.currentRow
      }
    }
    return null
  }
}

ComponentWillUpdate

  • React > 16.3: Caso queira executar alguma ação após o componente receber alguma chamada externa, prefira o uso de componentDidUpdate, pois componentWillUpdate será descontinuado na versão 17.
// Bad
class ExampleComponent extends Component {
  componentWillUpdate(nextProps, nextState) {
    if (this.state.someStatefulValue !== nextState.someStatefulValue) {
      nextProps.onChange(nextState.someStatefulValue);
    }
  }
}

// Good
class ExampleComponent extends Component {
  componentDidUpdate(prevProps, prevState) {
    if (this.state.someStatefulValue !== prevState.someStatefulValue) {
      this.props.onChange(this.state.someStatefulValue)
    }
  }
}

Component ou PureComponent

  • PureComponent é similar ao Component. A diferença está no shouldComponentUpdate(). Em PureComponent isto é feito de forma superficial no estado e props. Utilize PureComponent somente em casos em que você saiba exatamente a estrutura das propriedades que irão ser recebidas pelo component. Em alguns casos, onde o seu componente sempre irá renderizar uma mesma estrutura, você pode utilizar para ganhar performance. Mais informações você vai encontrar na documentação do React.

Valores padrões em parâmetros

  • Sempre que possível, crie valores padrões nos parâmetros da sua função
// Bad
const getPrice = (amount, scale, currency) => {
  return priceNormalize(parseFloat(inScale(amount, scale), 10), currency)
}

// Good
const getPrice = (amount = 0, scale = 2, currency = 'BRL') => {
  return priceNormalize(parseFloat(inScale(amount, scale), 10), currency)
}

Classes - Padding Line

  • When creating classes use blank line after
// Bad
class MyComponent extends Component {
  componentDidMount() {
    ...
  }
}

// Good
class MyComponent extends Component {

  componentDidMount() {
    ...
  }
}

Return - Padding Line

  • When return used requires a blank line between a variable declaration and a return statement
// Bad
render () {
  const { name } = this.props
  return (
    <h1>
      {name}
    </h1>
  )
}

// Good
render () {
  const { name } = this.props

  return (
    <h1>
      {name}
    </h1>
  )
}