Skip to content

kevinveiga/react-hooks-boilerplate

Repository files navigation

PADRÕES

  • Nomes no singular: Todas as pastas;
  • Idioma inglês: Todos os nomes, exceto nomes próprios, como seções ou páginas;
  • lowerCamelCase: Nomes de variáveis, funções, métodos - Ex: functionName;
  • UpperCamelCase: Nomes de imports, classes, interfaces, pastas de componentes, arquivos de componentes - Ex: ClassName, Header.js;
  • spinal-case: Nomes no CSS, arquivos no geral, exceto pastas de componentes e arquivos de componentes - Ex: topo-imagem-1.jpg, Header.js;
  • snake_case: Nomes de pastas, exceto pastas de componentes - Ex: folder_name, ComponenteA;

INSTALAÇÕES NECESSÁRIAS PARA O PROJETO

CONFIGURAÇÃO:

  • Configurar arquivos .env*

FRONTEND

IDE - INSTALAÇÃO DE PLUGINS:

  • EditorConfig (exemplo no VS Code: EditorConfig for VS Code)
  • ESLint (exemplo no VS Code: ESLint)
  • Prettier (exemplo no VS Code: Prettier - Code formatter)
  • Styled Components (exemplo no VS Code: vscode-styled-components (Julien Poissonnier))

IDE - CONFIGURAÇÃO:

  • Configurar para formatar o código ao salvar o arquivo

IDE - VS CODE CONFIGURAÇÃO:

"[javascript]": {
 "editor.defaultFormatter": "esbenp.prettier-vscode"
 },
"editor.formatOnSave": true,
"files.watcherExclude": {
 "**/.git/objects/**": true,
 "**/.git/subtree-cache/**": true,
 "**/node_modules/*/**": true
 },
"git.autofetch": true

Executar apenas a primeira vez no terminal:

  • npm i -g npm (atualiza NPM)
  • npm i (instala pacotes de tarefas)
  • npm audit fix (corrigir pacotes)

Ambiente de desenvolvimento, executar no terminal:

  • npm run dev

Ambiente de produção, executar no terminal:

  • npm run prod

Caso ocorra algum erro posteriormente, executar no terminal:

  • npm i

React

  • Evitar a utilização de export default (exceto para React Lazy and Suspense);

  • Organizar "import" na ordem correta, tanto na ordem de contexto como na ordem alfabética. Ex:

// React import
import React from 'react';

// Library import
import { BrowserRouter } from 'react-router-dom';
import { ThemeProvider } from 'styled-components';

// Application import
import { Router } from './router';

// Service import
import { useSeoApi } from './service/seo';

// Store import
import { AuthProvider } from './store/auth/auth';

// Utility import
import { customValidate } from './util/customValidate';

// Component import
import { Modal } from './component/Modal/Modal';

// Component Styled import
import { Modal } from './component/Modal/ModalStyled';

// Style import
import { Normalize } from './style/normalize';
import { theme } from './style/theme';

// Image import
import imageName from './asset/image/imageName.jpg';
  • Ao definir um nome de variável para um State de Contexto, colocar no final do nome "Context". Ex:
<PesquisaContext.Provider value={{ setStatePesquisaDataContext: memoPesquisa[1] }}>...</PesquisaContext.Provider>
  • Ao criar um arquivo de Styled Component referente a um componente, colocar no final do nome "Styled". Ex: HomeStyled.js;

  • Ao definir um nome para o Styled Component referente a um componente, colocar no final do nome "Styled". Ex:

export const VideoContainerStyled = styled.section`...`;
  • No return do JSX, caso não existam os dados, passar null. Ex:
return stateBanner.data && stateBanner.data.sidebar_habilitada == '1' ? (
    <BannerStyled change={stateChangeBannerScroll} fadeOut={stateFadeOutBannerScroll} {...otherProps}>
        {parse(`${stateBanner.data.sidebar}`)}
    </BannerStyled>
) : null;
  • Usar sempre a propriedade "key" nos elementos HTML em loops do React, usando como valor um id e não um índice. Ex:
<li key={list.id}>{list.text}</li>
  • Para usar funções em eventos, utilizar da seguinte maneira:
const handle = useCallback(
    (value) => (e) => {
        console.log('valor do parâmetro', value);
        console.log('elemento', e);
    },
    []
);
<div onClick={handle(true)}>...</div>
  • Ao utilizar Styled System, cuidar para não usar a mesma propriedade no Style Components. Ex:
<Box width="100%">...</Box>

ERRADO

export const Box = styled.div`
    ${layout}
    width: 500px;
`;
o correto é verificar se a propriedade é "undefined", e nesse caso, usar o valor default. Ex:

CERTO

export const Box = styled.div`
    ${layout}
    ${({ width }) => width === undefined && 'width: 500px'};
`;

React - Forms | Como usar:

  • Utilização da biblioteca React Hook Form;

  • O tipo e controle dos campos é feito com o modo "control" e o componente Controller da biblioteca;

  • Na maioria dos casos, a declaração do useForm fica assim:

const {
    control,
    errors,
    formState: { touched },
    handleSubmit,
    setError
} = useForm({
    mode: 'onChange'
});
  • Para passar valores iniciais nos campos, utilizar na declaração do useForm o "defaultValues". Ex:
const {
    control,
    errors,
    formState: { touched },
    handleSubmit,
    setError
} = useForm({
    defaultValues: { ...data, data_nasc: formatDateGet(data.data_nasc) },
    mode: 'onChange'
});
  • Para campo sem validação, usar como no exemplo abaixo:
<Controller
    control={control}
    name="query"
    render={({ name, onBlur, onChange, value }) => {
        return (
            <Input
                autoComplete="off"
                maxLength="50"
                name={name}
                onBlur={onBlur}
                onChange={(e) => {
                    onChange(e.target.value);
                }}
                onKeyDown={keyPress(onSubmit)}
                placeholder="O que você procura?"
                ref={queryRef}
                value={value}
                {...props}
            />
        );
    }}
/>
  • Para campo com validação, usar como no exemplo abaixo:
<Controller
    control={control}
    name="email"
    render={({ name, onBlur, onChange, value }) => {
        return (
            <InputValidation
                error={errors.email}
                maxLength="50"
                name={name}
                onBlur={onBlur}
                onChange={(e) => {
                    onChange(e.target.value);
                }}
                pr={4}
                touched={touched}
                value={value}
                {...otherProps}
            />
        );
    }}
    rules={{ ...customValidate.email, ...customValidate.require }}
/>
  • Para usar um "label" como comportamento de "placeholder" no campo "input", basta passar a propriedade "label". Ex:
<Controller
    control={control}
    name="email"
    render={({ name, onBlur, onChange, value }) => {
        return (
            <InputValidation
                error={errors.email}
                label="E-mail"
                maxLength="50"
                name={name}
                onBlur={onBlur}
                onChange={(e) => {
                    onChange(e.target.value);
                }}
                pr={4}
                touched={touched}
                value={value}
                {...otherProps}
            />
        );
    }}
    rules={{ ...customValidate.email, ...customValidate.require }}
/>
  • Para máscara simple no campo, usar o componente "InputMask" (sem validação) ou "InputMaskValidation" (com validação), como no exemplo abaixo:
<Controller
    control={control}
    name="telefone"
    render={({ name, onBlur, onChange, value }) => {
        return (
            <InputMaskValidation
                error={errors.telefone}
                format="(##) #####-####"
                label="Celular"
                name={name}
                onBlur={onBlur}
                onValueChange={(values) => {
                    onChange(values.value);
                }}
                pr={4}
                touched={touched}
                value={value}
                {...otherProps}
            />
        );
    }}
    rules={{ ...customValidate.cellphone, ...customValidate.require }}
/>
  • Para máscara monetária no campo, usar o componente "InputMask" (sem validação) ou "InputMaskValidation" (com validação), como no exemplo abaixo:
<Controller
    control={control}
    name="valor"
    render={({ name, onBlur, onChange, value }) => {
        return (
            <InputMask
                decimalScale={2}
                decimalSeparator=","
                isNumericString={true}
                maxLength="15"
                onBlur={onBlur}
                onValueChange={(values) => {
                    onChange(values.value);
                }}
                pr={4}
                thousandSeparator="."
                value={value}
                {...otherProps}
            />
        );
    }}
/>
  • Campos do tipo checkbox ou radio, no "onChange" usar como no exemplo abaixo:
<Controller
    control={control}
    name="receber_avisos_descontos_de_cursos"
    render={({ name, onBlur, onChange, value }) => {
        return (
            <InputCheckboxRadio
                checked={data.receber_avisos_descontos_de_cursos}
                color="colorGray2"
                id="receber_avisos_descontos_de_cursos"
                name={name}
                onBlur={onBlur}
                onChange={(e) => onChange(e.target.checked)}
                value={value}
            >
                <Span fontSize={{ d: '14px', sm: '16px' }} verticalAlign="middle">
                    Desejo receber avisos e descontos de cursos
                </Span>
            </InputCheckboxRadio>
        );
    }}
/>

React - Referências:

Boas práticas:

Configuração:

Estrutura de pastas e arquivos:

Padrão de desenvolvimento no código:

Helmet:

Hooks - Components:

Hooks - Fetch Data:

Hooks - Forms:

Hooks - State:

Lazy and Suspense:

  • React Lazy and Suspense; Neste exempĺo é usado no React Router, mas no projeto não foi utilizado para não prejudicar no SEO, por tanto, utilize Lazy and Suspense somente em componentes que realmente podem ser carregados depois;

Router:

Styled Component:

Styled System:

Javascript

  • Ao utilizar métodos do ES6 sempre verificar se tem suporte para IE11+, de preferência para métodos do ES5;
  • Priorizar os seletores nativos como "document.getElementById" ou "document.querySelector";
  • Javascript modular;
  • Strings utilizar apóstrofo - Ex: 'texto';
  • Utilizar JSDOC;

Libs

Links externos em elementos <a/> com target="_blank"

  • Utilizar rel="noopener noreferrer" Link;

Svg

  • Referência de uso;
  • Sempre otimizar código do Svg, juntando formas, removendo código desnecessário, entre outras otimizações;
  • Minificar código, utilizar site https://jakearchibald.github.io/svgomg/;
  • No site de otimização, usar o valor 2 na precisão;
  • Utilizar como componente React;

Referências Webpack 4:

Referências Workbox:

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published