Componentizando com React
Tags: typescript, beginners, react, webdev
Published: 2022-08-11 16:43:53

Esta documentação foi pensada para ajudar pessoas que estão começando a desenvolver apps com React e nao entendem a complexidade da doc oficial. Existem vários caminhos, este é o mais usual e simples, pensado pela equipe que desenvolveu o React.

![imagem de capa da introduçao](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/49w3jfarnl8ssxsbb0cl.png)

# INTRODUÇÃO

Quando desenvolvemos uma aplicação usando React, torna-se bem comum a componentização dos conteúdos. Quando a fazemos de forma sólida e concisa, separando responsabilidades em cada componente e unindo todos para um propósito, conseguimos ter um modelo mental ideal da aplicação.

 
Neste projeto utilizamos Typescript (um superset do Javascript) e TailwindCSS para facilitar o nosso CSS.

# Comece Com Um Mock

Suponha que você já tenha design de uma lista de carros com marca, modelo, ano e preço desenvolvida.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ryicj5txflf5qj2a8zg9.png)

Nossa API JSON deve retornar dados como esses:

```tsx
[
  {brand: "Ford", model: "Fiesta", year: 2008, color: "Blue", price: 14000,},
  {brand: "Ford", model: "Focus", year: 2009, color: "Silver",price: 16000,},
  {brand: "Ford", model: "Mondeo", year: 2010, color: "Black", price: 18000,},
  {brand: "Ford", model: "Mustang", year: 2011, color: "Red", price: 20000,},
  {brand: "Ford", model: "Taunus", year: 2012, color: "White", price: 22000,},
]
```
# Etapa 1: separar a interface do usuário em uma hierarquia de componentes

A primeira coisa a se fazer é desenhar retângulos em volta de cada componente e subcomponente, se houver,  mostrado no mock. Separe por cores para melhorar a visualização.

Mas como saber o que é componente e subcomponente? Use o mesmo conhecimento que você usaria para decidir se você deve criar uma função ou um objeto. Uma boa técnica é o [princípio da responsabilidade única,](https://en.wikipedia.org/wiki/Single-responsibility_principle) que diz que um componente deve servir a apenas um propósito. Se ele acabar crescendo, deverá ser decomposto em componentes menores, que são os subcomponentes.

Agora, vamos separar a nossa UI em componentes:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m65igydpkhgy92qwczy4.jpeg)

Conseguimos separar a nossa lista de carros em 4 componentes:

1. FilterableProductTable (VERDE): Abriga todos os componentes;
2. SearchInput (VERMELHO): Recebe a entrada do usuário;
3. CarsTable (AZUL): exibe e filtra a coleção de dados baseado na entrada do usuário;
4. CarRow (LARANJA): Exibe uma linha para cada carro.

Você deve ter se perguntado: “Mas e o cabeçalho da tabela? Não é um componente separado?”.  A resposta é: depende! Na medida que a tabela crescer, se houver a necessidade de uma ordenação, por exemplo, certamente podemos componentizar o cabeçalho em um CarTableHeader. Neste caso, como é só a exibição estática dos nomes dos cabeçalhos, manteremos a responsabilidade atrelada à CarsTable.

Agora que identificamos os componentes do nosso mock, vamos trabalhar. Componentes que estão dentro de outros, devem aparecer como filhos na hierarquia. Organizamos da seguinte maneira:

- FilterableProductTable
    - SearchInput
    - CarsTable
        - CarRow

# Etapa 2: Crie Uma Versão Estática Em React

Iniciar sempre o trabalho no frontend com REACT utilizando um mock (dados fictícios) para simular a request da API no front é vantajoso pois exclui a necessidade de integração com o backend. Siga a documentação para replicar como seria o retorno da API.

Este é um exemplo de um mapa dos dados da lista (representando nosso JSON)

```tsx
const carsData: Array<{
 brand: string;
 model: string;
 year: number;
 color: string;
 price: number;
}> = [
 {
   brand: "Ford",
   model: "Fiesta",
   year: 2008,
   color: "Blue",
   price: 14000,
 },
 {
   brand: "Ford",
   model: "Focus",
   year: 2009,
   color: "Silver",
   price: 16000,
 },
 {
   brand: "Ford",
   model: "Mondeo",
   year: 2010,
   color: "Black",
   price: 18000,
 },
 {
   brand: "Ford",
   model: "Mustang",
   year: 2011,
   color: "Red",
   price: 20000,
 },
 {
   brand: "Ford",
   model: "Taunus",
   year: 2012,
   color: "White",
   price: 22000,
 },
];
```
Com o mock em mãos, monte uma lista estática. Apenas o necessário para mostrar na tabela os dados do mock.  

```tsx
export type StaticFilterableProductTableProps = {};

const StaticFilterableProductTable =
 ({}: StaticFilterableProductTableProps) => {
   return (
     <div className="flex flex-col h-screen w-screen bg-slate-200 
			 items-center justify-center">
       <div className="flex items-start justify-start">
         <input
           className="border-2 border-gray-300 rounded-lg p-2 
			 focus:border-blue-300 focus:outline-none"
           placeholder="Search ... "
         />
       </div>
       <div>
         <table className="table-auto mt-8">
           <thead>
             <tr>
               <th className="px-4 py-2">Brand</th>
               <th className="px-4 py-2">Model</th>
               <th className="px-4 py-2">Year</th>
               <th className="px-4 py-2">Color</th>
               <th className="px-4 py-2">Price</th>
             </tr>
           </thead>
           <tbody>
             {carsData.map((car, index) => (
               <tr key={index}>
                 <td className="border px-4 py-2">{car.brand}</td>
                 <td className="border px-4 py-2">{car.model}</td>
                 <td className="border px-4 py-2">{car.year}</td>
                 <td className="border px-4 py-2">{car.color}</td>
                 <td className="border px-4 py-2">${car.price}</td>
               </tr>
             ))}
           </tbody>
         </table>
       </div>
     </div>
   );
 };
export default StaticFilterableProductTable;
```

# Etapa 3: Controlando os Componentes

Gosto de chamar esta etapa de ‘Aprendizado do componente’, é quando deixamos ele inteligente. Deixamos um pouco o JSX e CSS de lado e damos atenção às funcionalidades do componente.

Sabemos que precisamos pegar o valor do input para filtrar a lista, uma maneira simples e eficaz neste cenário é usar o useState hook do React para nos ajudar a gerenciar este estado (leia mais em [Introdução aos Hooks](<https://pt-br.reactjs.org/docs/hooks-intro.html>) ).

Sempre abusando de boas práticas, é interessante colocar um nome adequado e específico para cada hook de acordo com seu propósito, vamos então chamar essa constante de `searchValue`, acompanhada de sua função que irá manipular o seu valor, o  `setSearchValue` .![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ni6mro9cclfofsf2wbot.png)
A partir deste ponto podemos colocar o nosso state para funcionar. Adicione a prop `value` da tag `<input>` e coloque como seu valor o `searchValue`. Adicione uma segunda prop, o **onChange** (um dos Event Handlers do React), e em sua callback uma arrow function anônima como `event` em seu parâmetro e retornando implicitamente **`setSearchValue`**, sendo seu valor `event.target.value`.

Adicione um console log fora do retorno para testar.![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j1qtmzym7cxvk0b20qz2.png)
Nosso input já está funcionando, mas não estamos filtrando nada ainda. O Array continua sendo o mesmo. Para dinamizar isso podemos fazer uma função antes do retorno do JSX. Vamos chamá-la de `filterCars`. Ela terá como parâmetro um array `cars` e compartilhando o mesmo tipo do array original de carros (já que estamos usando TS) que retorna um novo array filtrado pelo modelo do produto, no caso os carros.

Considere colocar uma condicional afirmando o retorno do array de carros original caso o searchValue esteja undefined.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xdvw029gkfajrt7pbx89.png)
Chamamos essa função no `map()` da listagem de carros na tabela, passando como parâmetro o nosso ‘array mock’ `carsData`.![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8o74mf3rdgedkwj0a426.png)

# CONCLUSÃO

Removemos os console.logs e então está feito! Nossa tabela está inteligente, filtrando e listando. Simples assim, como deve ser.

Definimos dados mocks para simular uma API, então criamos o componente estático apenas com JSX e css (no meu caso usei Tailwindcss) e uma pitada de js, então deixamos o componente mais dinâmico e inteligente para servir ao seu propósito, ser uma tabela que lista e filtra produtos.

Aprendemos principalmente a ordem de como lidar com React. Construir componentes React ficou mais fácil e rápido!
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydqeo6qvkjy9puk044f6.gif)
 
  # REFERÊNCIAS

1. [Pensando do jeito React](https://pt-br.reactjs.org/docs/thinking-in-react.html)