Repository: rubenmarcus/guiareact.org
Branch: main
Commit: 74244731e869
Files: 16
Total size: 33.2 KB
Directory structure:
gitextract_igeb4d_j/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ └── discussion.md
│ └── pull_request_template.md
├── .gitignore
├── README.md
├── components/
│ ├── header.js
│ ├── mdcontainer.js
│ └── pagehead.js
├── config/
│ ├── md-loader.js
│ └── static-paths.js
├── documentation/
│ └── DOC-HOME.md
├── next.config.js
├── package.json
├── pages/
│ ├── _app.js
│ ├── _document.js
│ └── index.js
└── styles/
└── style.css
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/discussion.md
================================================
---
name: Issue de discussão
about: Sugestões, alterações, correções, etc.
title: ''
labels: ''
assignees: ''
---
## O que?
(Escreva aqui.)
## Por quê?
(Escreva aqui.)
## Referências
(Escreva aqui.)
================================================
FILE: .github/pull_request_template.md
================================================
## Descrição
(Escreva aqui.)
## O que foi feito nesse PR?
- [x] Tarefa já realizada
- [ ] Tarefa à ser feita
## Dependência de outras Issues
> Exemplo: #1
>
================================================
FILE: .gitignore
================================================
./node_modules
node_modules
node_modules/*
./.next
.next
================================================
FILE: README.md
================================================
# guiareact.org
Site em Português com tradução do Original reactpatterns.com de Michael Chan - [@chantastic](https://github.com/chantastic)
https://guiareact.org
## CONTRIBUA
- Clone o projeto em sua máquina
- Edite ou Crie os arquivos MD na pasta **documentation**
- Abra uma [Issue](https://github.com/rubenmarcus/guiareact.org/issues/new).
- Crie um [P/R](https://github.com/rubenmarcus/guiareact.org/compare) e adicione o link na sua issue.
## ROADMAP
- TROCAR TODOS EXEMPLOS DE CLASSE PARA EXEMPLOS COM COMPONENTES FUNCIONAIS
- ADICIONAR GUIA DE HOOKS
- ADICIONAR MAIS EXEMPLOS
- ADICIONAR GUIA DE NEXT.JS
- ADICIONAR GUIA DE CSS IN JS
- ADICIONAR GUIA DE REDUX
- ADICIONAR GUIA DE CONTEXT API
================================================
FILE: components/header.js
================================================
export default function AppHeader(props){
return(
{props.title}
)
}
================================================
FILE: components/mdcontainer.js
================================================
import ReactMarkdown from "react-markdown";
import remarkSlug from "remark-slug";
import remarkLinks from "remark-external-links";
import remarkHljs from "remark-highlight.js";
import remarkToc from "remark-toc";
export default function MdContainer({ markdown }) {
const remarkPluginSet = [remarkSlug, remarkLinks, remarkHljs, remarkToc];
return ;
}
================================================
FILE: components/pagehead.js
================================================
export default function PageHead(props) {
const GA_TRACKING_ID = "G-TQFVHD7RW1";
return (
<>
{props.title? props.title : 'Guia de Padrões React'}
>
);
}
================================================
FILE: config/md-loader.js
================================================
import Hooks from "../documentation/DOC-HOOKS.md";
import Contribua from "../documentation/DOC-CONTRIBUA.md";
import Links from "../documentation/DOC-LINKS.md";
const MdLoader = {
hooks: Hooks,
contribua: Contribua,
links: Links,
};
export default MdLoader;
================================================
FILE: config/static-paths.js
================================================
const ROUTES = [
{ params: { slug: "hooks", title: "Guia de Hooks" } },
{ params: { slug: "contribua", title: "Guia de Padrões React" } },
{ params: { slug: "links", title: "Guia de Padrões React" } },
];
export const STATIC_PATHS = { paths: ROUTES, fallback: false };
export const PATH_PROPS = (slug) =>
STATIC_PATHS.paths.filter(({ params }) => params.slug === slug)[0].params;
================================================
FILE: documentation/DOC-HOME.md
================================================
# Guia de Padrões React
Um guia de padrões React em Português.
Baseado no [Original](https://reactpatterns.com) por Michael Chan [@chantastic](https://github.com/chantastic)
Traduzido para Português e revisado por [@rubenmarcus](https://github.com/rubenmarcus)
com contribuição de [@LhuizF](https://github.com/LhuizF), [@matheusinfo](https://github.com/matheusinfo), [@luizwbr](https://github.com/luizwbr), [@arimariojesus](https://github.com/arimariojesus), [@gabepinheiro](https://github.com/gabepinheiro), [@GusttavoCastilho](https://github.com/GusttavoCastilho) e [@azraelgarden](https://github.com/azraelgarden).
## Conteúdo
- [Traduções](#traduções)
- [Elementos](#elementos)
- [Componentes](#componentes)
- [Fragmentos](#fragmentos)
- [Sintaxe curta](#sintaxe-curta)
- [Exemplo com lista de componentes](#exemplo-com-lista-de-componentes)
- [Expressões](#expressões)
- [Props (Propriedades)](#props-propriedades)
- [defaultProps (Propriedades Padrão)](#defaultprops-propriedades-padrão)
- [Desestruturando props](#desestruturando-props)
- [Atributos de spread JSX](#atributos-de-spread-jsx)
- [Mergeando props desestruturadas com outros valores](#mergeando-props-desestruturadas-com-outros-valores)
- [Renderização Condicional](#renderização-condicional)
- [`if`](#if)
- [`unless` (ao menos que)](#unless-ao-menos-que)
- [`if-else` (Operador Ternário)](#if-else-operador-ternário)
- [Tipos de filhos (Children Types)](#tipos-de-filhos-children-types)
- [`String`](#string)
- [`Array`](#array)
- [Array como filho (Array as children)](#array-como-filho-array-as-children)
- [Função como filha (Function as children)](#função-como-filha-function-as-children)
- [Render prop](#render-prop)
- [Passando um Filho (Children)](#passando-um-filho-children)
- [Componente Proxy](#componente-proxy)
- [Estilizando componentes](#estilizando-componentes)
- [Switch de Eventos](#switch-de-eventos)
- [Componente de Layout](#componente-de-layout)
- [Container Components](#container-components)
- [Higher-order components](#higher-order-components)
- [Elevando o state (state hoisting)](#elevando-o-state-state-hoisting)
- [Inputs Controlados](#inputs-controlados)
## Traduções
Traduções não verificadas, e links não significam que são aprovadas.
[Chinese](https://reactpatterns.cn)
## Elementos
[Elementos](https://pt-br.reactjs.org/docs/glossary.html#elements) são tudo que está envolvido por <>.
```jsx
```
[Componentes](#componentes) retornam Elementos.
## Componentes
Um [Componente](https://pt-br.reactjs.org/docs/glossary.html#components) é definido por uma função que declarada retorna um [Elemento](#elementos) React.
```jsx
function MeuComponente() {
return
Olá Mundo
;
}
```
## Fragmentos
Um [Fragmento](https://pt-br.reactjs.org/docs/fragments.html) permite agrupar uma lista de filhos sem adicionar nós extras ao DOM.
```jsx
function MeuComponente() {
return (
Olá
Mundo
);
}
```
Isto renderizará no DOM apenas os seguintes elementos:
```html
Olá
Mundo
```
### Sintaxe Curta
Existe uma sintaxe nova e mais curta que você pode utilizar para declarar fragmentos. São as tags vazias:
```jsx
function MeuComponente() {
return (
<>
Olá
Mundo
>
);
}
```
## Expressões
Use chaves para [Incorporar expressões](https://pt-br.reactjs.org/docs/introducing-jsx.html#embedding-expressions-in-jsx) no [JSX](https://pt-br.reactjs.org/docs/glossary.html#jsx).
```jsx
function OlaUsuario() {
const nome = "Ruben";
return
Olá {nome}!
;
}
```
## Props (Propriedades)
Entenda como `props` como um argumento externo para possibilitar customizações para seu componente.
```jsx
function DigaOla(props) {
return
Olá {props.nome}!
;
}
```
## defaultProps (Propriedades Padrão)
Especificar valores padrão de `props` com `defaultProps`.
```jsx
function OlaUsuario(props) {
return
Olá {props.nome}!
;
}
OlaUsuario.defaultProps = {
nome: "Visitante",
};
```
## Default function parameters (parâmetros predefinidos de uma função)
Especificar valores padrão de `props` com `default function parameters`.
Os parâmetros predefinidos de uma função permitem que parâmetros regulares sejam inicializados com valores iniciais caso `undefined` ou nenhum valor seja passado.
```jsx
// Utilizamos aqui uma desestruturação no objeto `props` para pegarmos a prop `nome`
function OlaUsuario({ nome = "Visitante" }) {
return
Olá {nome}!
;
}
```
---
## Desestruturando props
[Atribuição via desestruturação](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) é um recurso do Javascript moderno.
Foi adicionado a linguagem no ES2015.
```js
const usuario = { nome: "Ruben" };
const { nome } = usuario;
```
Funciona com Array também.
```js
const numeros = ["um", "dois"];
const [um, dois] = numeros;
```
Atribuição via desestruturação (Destructuring assignment) é usado muito em [componentes funcionais](#function-component).
Essas declarações de componente são equivalentes.
```jsx
const Ola = (props) =>
Olá {props.name}!
;
const Ola = ({ name }) =>
Olá {name}!
;
```
Existe uma sintaxe para atribuir as `props` restantes em um objeto.
Se chama [Parâmetros](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Functions/rest_parameters) e parece assim:
```jsx
const Ola = ({ name, ...restProps }) =>
Olá {name}!
;
```
Esses três pontos (`...`) pegam todas a props que faltam e atribuem ao parâmetro `restProps`.
Então o que fazer com `restProps` quando você o tem?
Continue lendo...
---
## Atributos de spread JSX
Atributos de Spread é uma feature do [JSX](https://pt-br.reactjs.org/docs/introducing-jsx.html).
É uma sintaxe para fornecer as propriedades de um objeto como atributos JSX.
Seguindo o exemplo de [Destructuring props](#desestruturando-props),
Podemos fazer **spread** com `restProps` em nossa `
;
};
```
Isso torna a função `Ola` super flexível.
Podemos passar atributos DOM para `Ola` e que eles vão ser passados a nossa `div`.
```jsx
```
Atribuição via desestruturação é popular porque fornece uma maneira de separar props específicas de componentes, de atributos específicos de plataforma / DOM.
```jsx
function Greeting({ name, ...platformProps }) {
return
Hi {name}!
;
}
```
---
## Mergeando props desestruturadas com outros valores
Componentes são abstrações.
Boas abstrações permitem extensão.
Considere esse componente que usa um atributo `class` para estilizar um `button`.
```jsx
function MyButton(props) {
return ;
}
```
Isso funciona muito bem até tentarmos estendê-lo com outra classe.
```jsx
Delete...
```
Nesse caso, `delete-btn` substitui `btn`.
A ordem importa para [Atributos de spread JSX](#atributos-de-spread-jsx).
O `props.className` sendo passado, substitui o `className` do nosso componente.
Podemos mudar a ordem, mas agora o `className` **nunca** vai ser nada além de `btn`.
```jsx
function MyButton(props) {
return ;
}
```
Precisamos usar a atribuição via desestruturação para obter o `className` e mergear com o `className` base.
Podemos fazer isso simplesmente adicionando todos os valores a uma array e juntando-os com um espaço..
```jsx
function MyButton({ className, ...props }) {
const classNames = ["btn", className].join(" ");
return ;
}
```
Para não ter problemas com `undefined` aparecendo no seu `className`, você pode atualizar sua lógica para pegar valores booleanos `falso`:
```jsx
function MyButton({ className, ...props }) {
const classNames = ["btn", className].filter(Boolean).join(" ").trim();
return ;
}
```
Porém, lembre-se de que, se um objeto vazio for passado, ele também será incluído na classe, resultando em: `btn [object Object]`.
A melhor abordagem é fazer uso de packages disponíveis, como [classnames](https://www.npmjs.com/package/classnames) ou [clsx](https://www.npmjs.com/package/clsx),que poderia ser usado para unir nomes de classe, evitando que você tenha que lidar com isso manualmente.
## Renderização Condicional
Você não consegue usar if else em suas declarações de componente..
Então vocês pode usar o operador ternário [conditional (ternary) operator](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) ou [short-circuit](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Short-circuit_evaluation) tranquilamente.
### `if`
```jsx
{
!!condition && Irá renderizar quando for `verdadeiro`;
}
```
Dica não utilize if dessa maneira:
```jsx
{
condition && Renderiza quando `verdadeiro`;
}
```
O React pode imprimir um `0` no seu componente. Quando vem `0` nos seus dados, ele não considera sua variável como falsa, utilizando o !! , ele converte 0 para falso
### `unless` (ao menos que)
```jsx
{
condition || Renderizado quando `falso`;
}
```
### `if-else` (Operador Ternário)
```jsx
{
condition ? (
Renderizado quando for `verdadeiro`
) : (
Renderizado quando for `falso`
);
}
```
## Tipos de filhos (Children Types)
O React consegue renderizar `children` da maioria dos tipos.
Na maioria dos casos é um `array` ou uma `string`.
### `String`
```jsx
Olá Mundo!
```
### `Array`
```jsx
{["Olá ", Mundo, "!"]}
```
## Array como filho (Array as children)
Prover um array como `children` é muito comum.
É como as listas são renderizadas no React.
Usamos o método `map()` para criar um array de elementos React para cada valor da array.
```jsx
{["primeiro", "segundo"].map((item) => (
{item}
))}
```
Esse é o equivalente a renderizar um `array` literal.
```jsx
{[
primeiro
,
segundo
]}
```
Este padrão pode ser combinado com desestruturação, Atributos de Spread JSX e outros componentes, para alguma coesão mais séria.
```jsx
```
## Função como filha (Function as children)
Componentes React não suportam funções como `children`.
Porém com o padrão, [render props](#render-prop) conseguimos criar componentes que tomam funções como `children` filhas.
## Render prop
Aqui um componente que utiliza `render callback`.
Não é útil, mas é um exemplo fácil para começar.
```jsx
const Width = ({ children }) => children(500);
```
Esse componente chama `children` como função, com alguns argumentos, nesse caso o número `500`.
Para usar esse componente estamos utilizando uma [Função como filha (Function as children)](#função-como-filha-function-as-children).
```jsx
{(width) =>
window é {width}
}
```
Recebemos esse output.
```jsx
window é 500
```
Com esta configuração, podemos usar essa prop `width` para fazer decisões de renderização.
```jsx
{(width) =>
width > 600 ?
condição de largura mínima atingida!
: null
}
```
Se planejamos usar muito essa condição, podemos definir outros componentes para encapsular a lógica reutilizada.
```jsx
const MinWidth = ({ width: minWidth, children }) => (
{(width) => (width > minWidth ? children : null)}
);
```
Claro que um componente `Width` estático não é útil, mas aquele que observa o window do navegador é. Aqui está um exemplo de implementação.
```jsx
function WindowWidth({ children }) {
const [width, setWidth] = useState(0);
useEffect(() => {
setWidth(window.innerWidth);
window.addEventListener("resize", ({ target }) =>
setWidth(target.innerWidth)
);
}, []);
return children(width);
}
```
Muitos desenvolvedores preferem [Higher Order Components](#higher-order-components) para este tipo de funcionalidade. É uma questão de preferência.
## Passando um Filho (Children)
Você pode criar um componente projetado para usar `context` e renderizar `children`.
```jsx
class SomeContextProvider extends React.Component {
getChildContext() {
return { some: "context" };
}
render() {
// como retornamos children?
}
}
```
Você está diante de uma decisão. Envolver os `filhos` em uma `` estranha que retorne o `children` diretamente. As primeiras opções adicionam marcação extra (que pode quebrar alguns css). O segundo resultará em erros inúteis.
```jsx
// option 1: extra div
return
{children}
;
// option 2: erros inúteis
return children;
```
É melhor tratar `children` como um tipo de dados opaco. O React fornece `React.Children` para lidar com `children` apropriadamente.
```jsx
return React.Children.only(this.props.children);
```
## Componente Proxy
_(Não tenho certeza se esse nome faz sentido)_
Os botões estão em todos os lugares nos aplicativos da web. E cada um deles deve ter o atributo `type` definido como `button` .
```jsx