Reference Style Guide
- Regras básicas
- Estrutura de componentes
- Criando componentes
- Exportando arquivos
- Custom hooks
- Arquivos em PascalCase
- Nomeando coisas
- Class Component
- Estilizando componentes
- Tipando componentes
- Testes unitários
- Alt em imagens
- Estruturas de pastas
- Um componente por arquivo
- Evite ao máximo o uso de
any
nas tipagens - Componentes unicamente em TSX
- Código apenas em inglês
Por que? Por mais que todos os contribuídores sejam brasileiros é importante padronizarmos todo o código em inglês para evitar uma mistura de inglês e português, algo do tipo "setNome()", um dos principais motivos também é a acessibilidade, muitas ferramentas de tradução automática e leitores de tela são mais eficazes quando lidam com texto em inglês.
- Separe a pasta do seu componente em 4 arquivos
- Componente.tsx (seu componente em si)
- Componente.spec.tsx (testes do componente)
- Componente.module.scss (seus estilos)
- Componente.types.ts (interfaces e types do componente)
├─ components
│ ├─ MyComponent.module.scss
│ └─ MyComponent.spec.tsx
│ └─ MyComponent.tsx
| └─ MyComponent.types.ts
Todos os componentes serão criados em funções normais
, arrow functions
apenas dentro dos componentes
// Bom
function Component(props: IProps) {
const handleSomething = () => { /* ... */ }
return ( /* ... */ )
}
// Ruim
const Component = (props: IProps) => {
const handleSomething = () => { /* ... */ }
return ( /* ... */ )
}
// Ruim
const Component = (props: IProps) => {
function handleSomething() { /* ... */ }
return ( /* ... */ )
}
Iremos usar SEMPRE export default
nos componentes
// Bom
function Component(props: IProps) {
return ( /* ... */ )
}
export default Component
// Ruim
export function Component(props: IProps) {
return ( /* ... */ )
}
// Ruim
function Component(props: IProps) {
const handleSomething = () => { /* ... */ }
return ( /* ... */ )
}
Com excessão dos componentes, não iremos usar export default
// Bom
export interface IProps {
/* ... */
}
// Ruim
interface IProps {
/* ... */
}
export default IProps;
Isso também vale para custom hooks
// Bom
export const useHook = () => {
/* ... */
};
// Ruim
const useHook = () => {
/* ... */
};
export default useHook;
Se precisar criar um custom hook, use arrow functions
// Bom
export const useHook = () => {
/* ... */
};
// Ruim
export function useHook() {
/* ... */
}
Iremos seguir o padrão PascalCase que consiste em nomear todas as palavras com a primeira letra maiúscula.
├─ components
│ ├─ MyComponentHere.tsx
Tirando componentes e interfaces, iremos utilizar camelCase
para nomear tudo.
// Bom
const handleSomething = () => {
/* ... */
};
// Ruim
const HandleSomething = () => {
/* ... */
};
// Ruim
const handle_something = () => {
/* ... */
};
Isso Inclue props de componentes
<MyComponent isHandsome name="hxsggsz" />
Se a prop é uma string sempre passe entre aspas, única excessão é se você for usar template string
// Bom
<MyComponent
isHandsome
name="hxsggsz"
/>
// Ruim
<MyComponent
isHandsome
name={"hxsggsz"}
/>
Oculte parâmetros que sempre serão true
// Bom
<button isLoading>teste<button>
// Ruim
<button isLoading={true}>teste<button>
Nosso projeto está sendo feito inteiramente com programação funcional
, então apenas use functional components
(salvo excessões bem excessíveis):
// Bom
function Component(props: IProps) { /* ... */ }
export default Component
// Ruim
class Component extends React.Component {
// ...
render() {
return ( /* ... */ )
}
}
Estamos utilizando scss modules
para estilização, ele tem umas diferenças do css normal
// Bom
.button {
/* seu css aqui */
&:hover {
/* seu css de hover aqui*/
}
}
// Ruim
.button {
/* seu css aqui */
}
.button:hover {
/* seu css de hover aqui*/
}
use scss modules
sempre
// Bom
import scss from "./Component.module.scss";
function Component(props: IProps) {
return <div className={scss.style} />;
}
// Ruim
import "./Component.scss";
function Component(props: IProps) {
return <div className="style" />;
}
Evite inline-css, sempre crie uma classe para estilizar.
Existem excessões em que é precisa usar inline styles
, mas são casos específicos e estarão atrelados a apenas uma propriedade
// Bom
import scss from "./Component.module.scss";
function Component(props: IProps) {
return <div className={scss.style} />;
}
// Ruim
function Component(props: IProps) {
return <div style={{ color: "#fff" }} />;
}
Priorize Interfaces
no lugar de Types
, ambos servem para fazer a mesma coisa, mas estamos seguindo o padrão de interfaces
// Bom
interface IProps {
/* ... */
}
// Ruim
type IProps = {
/* ... */
};
Use o Prefixo I
na hora da criação de interfaces.
// Bom
interface IProps {
/* ... */
}
// Ruim
interface PropTypes {
/* ... */
}
Use o Prefixo T
na hora da criação de tipos.
// Bom
type TProps = {
/* ... */
};
// Ruim
type PropTypes = {
/* ... */
};
Use o Prefixo E
na hora da criação de enums.
// Bom
enum ECoisas = { /* ... */ }
// Ruim
type Coisas = { /* ... */ }
Tente ser o mais claro para descrever seus testes, descreva a ação que você vai fazer como describe()
e use o it()
para descrever a ação esperada do teste. Siga esse padrão:
Evite a palavra "should" seguida do it
, faça sua sentença ser hiperativa, como "it has", "it renders", "it fails" e etc. Isso serve pra evitar que toda descrição de um teste inicie por "should".
describe("MyButtonComponent", () => {
describe("when initialize", () => {
it("shows the button on screen", () => {
// ...
});
describe("when click", () => {
it("calls the handleButton function ", () => {
// ...
});
});
});
});
SEMPRE coloque o atributo alt
quando for usar alguma imagem no projeto, é bom por causa do SEO
(mesmo que esse projeto não seja web) e acessibilidade.
// Bom
<img src={image} alt="me and my dog" />
// Ruim
<img src={image} />
Evite usar o prefixo image
ou picture
porque os leitores de tela ja adicionam esse prefixo na hora de ler o alt
então ficaria duplicado
// Ruim
<img src={image} alt="image about me and my dog" />
├─ public
│ ├─ coisas de fato publicas como robots.txt, favicons, sitemap.xml e etc.
├─ src
│ ├─ App.tsx
| | ├─ Root provider
│ ├─ components
| | ├─ Componentes de alta usabilidade
│ ├─ hooks
| | ├─ Hooks customizados de alta reusabilidade
│ ├─ pages
| | ├─ Páginas da aplicação
│ ├─ store
| | ├─ Store geral da aplicação
│ ├─ styles
| | ├─ Estilos globais
│ ├─ utils
| | ├─ Funções/classes de alta reusabilidade
│ ├─ services
| | ├─ Serviços externos a aplicação
│ ├─ config
| | ├─ Configurações de módulos
│ ├─ snippets
| | ├─ Snippets usados na aplicação
│ ├─ interfaces
| | ├─ Interfaces que não são relativas a um módulo específico
│ ├─ constants
| | ├─ Constantes que não são relativas a um módulo específico
│ ├─ enums
| | ├─ Enums que não são relativos a um módulo específico