Projetos React podem facilmente se tornar uma bagunça. Perder o controle de onde os arquivos estão localizados é extremamente comum, o que pode levar a ineficiências significativas durante o desenvolvimento. Então, como você pode melhorar e organizar seus projetos React? Organizando todos os arquivos do seu projeto em uma arquitetura de várias camadas.

Como resultado, você sempre saberá como colocar-e encontrar-cada arquivo. Esta é uma virada de jogo. Isso não apenas o tornará um desenvolvedor mais eficiente, mas também tornará seu projeto muito mais sustentável.

Além disso, ao transformar projetos em arquiteturas organizadas, toda a sua equipe também pode se beneficiar. Isso ocorre porque pessoas diferentes podem trabalhar em camadas diferentes, evitando sobreposição e sobrecarga potencial.

Vejamos por que você deseja usar estruturas de várias camadas no React.

Como as estruturas em várias camadas otimizam os aplicativos React

Reutilizando código

Imagine todos os seus projetos React compartilhando a mesma estrutura de arquivo em várias camadas, permitindo que você maximize seu tempo. Em vez de adaptar componentes ou arquivos importados de outras bases de código para seu projeto de destino, esta estrutura de arquivo compartilhada permite que você importe qualquer tipo de arquivo ou fragmento de código de um projeto para outro como uma operação simples de copiar e colar. Isso incentiva a reutilização de código, tornando mais fácil e menos demorado para você construir seu aplicativo.

Por exemplo, digamos que você tenha vários problemas matemáticos em um de seus projetos. Ao usar essa estrutura de arquivo, você não fica tentado a espalhar todas as funções de utilitário necessárias em toda a base de código.

Em vez disso, ele o incentiva a definir um arquivo math-utils.js onde você pode armazenar todos os seus utilitários matemáticos. Além disso, ao externalizar elementos com a mesma finalidade no mesmo arquivo, você os torna mais reutilizáveis. Na verdade, se você enfrentar problemas semelhantes em um projeto futuro, pode simplesmente copiar o arquivo math-utils.js definido anteriormente e colá-lo na camada utils .

Evitando duplicação de código

A consequência de impor uma estrutura em várias camadas é que cada arquivo, função ou parte do código pertence a um determinado lugar. Isso significa que antes de escrever algo novo, você deve olhar primeiro na pasta assumida, o que desencoraja a duplicação de código e a redução do tamanho da compilação.

Um pacote com muito mais código do que o necessário obviamente será maior do que o necessário. Isso não é bom para navegadores, que precisam fazer o download e renderizar o código.

Portanto, evitar a duplicação de código torna seu aplicativo mais limpo, mais fácil de construir e mais rápido quando é renderizado. Por exemplo, sempre que você precisar recuperar os dados retornados de uma API específica, pode ser tentado a seguir esta abordagem:

 função FooComponent1 (props) { //... //recuperando dados fetch (`/api/v1/foo`) .então ((resp)=> resp.json ()) .então (função (dados) { resultados const=dados.resultados; //manipulando dados... }) .catch (função (erro) { console.log (erro); }); //lógica do componente...
} exportar FooComponent1 padrão 
 função FooComponent2 (props) { //... //recuperando dados fetch (`/api/v1/foo`) .então ((resp)=> resp.json ()) .então (função (dados) { resultados const=dados.resultados; //tratando dados de uma maneira diferente de FooComponent1... }) .catch (função (erro) { console.log (erro); }); //lógica de componente diferente de FooComponent1...
} exportar FooComponent2 padrão

Como você pode ver, FooComponent1 e FooComponent2 são afetados por um problema de duplicação de código. Em particular, o endpoint da API está sendo duplicado, forçando você a atualizá-lo sempre que ele mudar.

Este não é um bom hábito. Em vez disso, você deve mapear a API na camada de API da seguinte maneira:

 export const FooAPI={ //... //mapeando a API de interesse get: function () { return axiosInstance.request ({ método:"GET", url: `/api/v1/foo` }); }, //... }

E, em seguida, use-o onde for necessário para evitar a duplicação de código:

 import React from"react";
importar {FooAPI} de"../../api/foo";
//... function FooComponent1 (props) { //... //recuperando dados FooAPI .obter() .então (função (resposta) { resultados const=response.data.results; //manipulando dados... }) .catch (função (erro) { console.log (erro); }); //lógica do componente...
} exportar FooComponent1 padrão 
 import React from"react";
importar {FooAPI} de"../../api/foo";
//... function FooComponent2 (props) { //... //recuperando dados FooAPI .obter() .então (função (resposta) { resultados const=response.data.results; //manipulando dados de uma maneira diferente de FooComponent1... }) .catch (função (erro) { console.log (erro); }); //lógica de componente diferente de FooComponent1...
} exportar FooComponent2 padrão

Agora, o endpoint da API é salvo em apenas um lugar, como deveria ser sempre.

Aproveitando a sinergia da equipe

Trabalhar com uma estrutura de arquivo bem conhecida significa que os membros das equipes de desenvolvimento estão todos na mesma página e a usam da mesma maneira.

Sempre que um membro da equipe mapeia uma nova API ou cria um novo arquivo utils ou um novo componente, por exemplo, qualquer membro da equipe poderá usá-lo imediatamente. E, como cada arquivo é colocado logicamente em uma pasta específica que todos sabem como (e onde) acessar, a sobrecarga de comunicação é reduzida ou completamente eliminada, agilizando os processos de desenvolvimento da empresa.

Um potencial efeito colateral da construção de estruturas em várias camadas

Criar módulos npm pode ser complexo

Há uma desvantagem potencial em ter uma arquitetura de arquivo tão organizada: os arquivos estão espalhados por muitas pastas, o que o força a usar importações relativas intensivamente. Isso representa um problema conhecido na criação de módulos npm.

As importações relativas estão sujeitas a falhas, especialmente ao tentar encapsular parte de sua base de código para torná-la publicável como módulos autônomos. Por um lado, isso certamente pode representar um desafio adicional ao tentar criar um pacote npm.

Por outro lado, isso pode ser facilmente evitado transformando as importações relativas em importações absolutas não quebráveis, conforme descrito aqui . Essa técnica permite que você gire isso:

 importar UserComponent de"../../components/UserComponent";
import userDefaultImage de"../../../assets/images/user-default-image.png";
importar {UserAPI} de"../../apis/user";

Para isso:

 importUserComponentfrom"@ components/UserComponent";
importe userDefaultImage de"@ assets/images/user-default-image.png";
importar {UserAPI} de"@ apis/user";

Portanto, usar muitas importações relativas não deve ser visto como um problema real.

Agora, vamos ver como projetar uma arquitetura eficiente em várias camadas para seus projetos em React e JavaScript.

Criando arquitetura multicamadas

Primeiro, vamos dar uma olhada no resultado final da arquitetura multicamadas. Lembre-se de que cada camada de nossa arquitetura deve ser incluída em uma pasta específica . Como esperado, é altamente recomendável dar a essas pastas os mesmos nomes das camadas em que a arquitetura consiste. Dessa forma, a recuperação de um arquivo torna-se intuitiva e rápida. Você também sempre saberá onde colocar um novo arquivo, o que é uma grande vantagem.

Esta é a aparência da estrutura final:

Estrutura da pasta final
Como você pode ver , cada camada da arquitetura é representada por uma pasta.

Agora, vamos mergulhar em cada uma das camadas em que consiste a arquitetura apresentada.

1. Camada API

Aproveitando uma promessa-cliente HTTP baseado em , como Axios , você pode definir uma função para cada API da qual seu aplicativo depende, encapsulando toda a lógica necessária para chamá-la. Dessa forma, você pode dividir onde as solicitações de API são definidas de onde são realmente usadas. Vamos ver como essa camada pode ser construída com um exemplo simples:

 const axiosInstance=axios.create ({ URL base:'https://yourdomain.org'
}); export const UserAPI={ getAll: function () { return axiosInstance.request ({ método:"GET", url: `/api/v1/users` }); }, getById: function (userId) { return axiosInstance.request ({ método:"GET", url: `/api/v1/users/$ {userId}` }); }, criar: função (usuário) { return axiosInstance.request ({ método:"POST", url: `/api/v1/users`, dados: usuário }); }, update: function (userId, user) { return axiosInstance.request ({ método:"PUT", url: `/api/v1/users/$ {userId}`, dados: usuário, }); },
}

Agora, você pode importar o objeto UserAPI para fazer a chamada onde você precisa, assim:

 import React, {useEffect, useState} de"react";
importar {UserAPI} de"../../api/user";
//... function UserComponent (props) { const {userId}=adereços; //... const [user, setUser]=useState (indefinido) //... useEffect (()=> { UserAPI.getById (userId).then ( função (resposta) { //tratamento de resposta setUser (response.data.user) } ).catch (função (erro) { //Manipulação de erros }); }, []); //...
} exportar UserComponent padrão;

Ao empregar Promise tecnologia, você pode coletar todas as suas definições de solicitações de API no mesmo lugar. Mas não vamos perder de vista o objetivo. Este artigo não pretende mostrar o que você pode conseguir com a camada de API, e você pode seguir this e isto para leitura adicional.

API La yer Folder
Organizar todos os arquivos que pertencem à camada API na mesma pasta.

Em vez disso, vamos nos concentrar no fato de que, com essa abordagem, você será capaz de definir uma camada totalmente dedicada às solicitações de API. Isso terá toda a lógica para lidar com as solicitações de API salvas em apenas um lugar, em vez de duplicar toda a lógica para chamar uma API sempre que precisar.

2. Camada de ativos

Seu projeto React pode depender de arquivos que não fazem parte estritamente de sua base de código, como arquivos multimídia. Ter um local para armazenar todos eles é a prática recomendada, pois você deve separá-los claramente de seu código. Observe que essa camada pode ser organizada em subpastas com base em tipos ou extensões para mantê-la organizada:

Sa Camada de ativos mple
Uma amostra de camada de ativos organizada por tipo.

Além disso, este é um bom lugar para armazenar todos os seus arquivos de tradução necessários em um aplicativo internacional que emprega uma estrutura de internacionalização, como i18next .

Todos os arquivos de tradução
Manter todos os arquivos de tradução i18next na pasta de traduções.

3. Camada de componente

É aqui que você deve colocar todos os seus componentes. Você deve ter uma pasta por componente, nomeada da mesma forma que o próprio componente. Essa pasta geralmente contém apenas dois arquivos: index.js e index.css . Eles representam onde o componente React é definido e onde seu estilo está contido, respectivamente.

Sample Component Layer
Um exemplo de camada de componente em ação.

Como seus componentes podem ser grandes, você deve pensar em organizá-los em uma estrutura aninhada. Encontrar um bom critério para alocá-los em subpastas nem sempre é uma tarefa simples.

Ao mesmo tempo, lembre-se de que você sempre pode alterá-lo em tempo real, reorganizando a estrutura em que seus componentes são armazenados como desejar.

4. Camada constante

Uma prática comum é definir todas as constantes usadas em seu aplicativo em um único arquivo constans.js . Em um projeto pequeno, essa abordagem pode parecer a melhor solução. Inevitavelmente, conforme seu arquivo fica maior, ele lentamente se transforma em uma bagunça.

É por isso que você deve dividir suas constantes em vários arquivos. Por exemplo, em um aplicativo internacional, você pode pensar em armazenar todas as chaves personalizadas usadas por i18next em um arquivo específico.

Desta forma, todas as constantes relacionadas ao i18n estariam no mesmo arquivo, tornando-as mais fáceis de serem gerenciadas. Da mesma forma, você pode seguir a última abordagem em outras circunstâncias, como no exemplo abaixo:

Dividindo todas as constantes do aplicativo
Dividindo todas as constantes do aplicativo em quatro arquivos diferentes.

5. Camada Redux

Esta é uma camada opcional e você deve defini-la apenas se seu aplicativo usar Redux . Conforme declarado na documentação oficial , Redux é um contêiner de estado previsível para Aplicativos JavaScript. Se você já trabalhou com o Redux, deve saber quantos arquivos ele requer.

Perder-se na multidão de Redux redutores e Ações redux é comum, especialmente para o último. Além disso, definir ações envolve código clichê. É por isso que usar uma biblioteca, como redux-actions , para gerenciar todas as suas ações é recomendado. Então, você poderá simplesmente obter uma estrutura organizada organizando seus arquivos da seguinte maneira:

Sa Camada Redux mple
Uma camada Redux de amostra composta por duas pastas e um arquivo.

Como mostrado acima, você pode colocar todos os seus redutores Redux na pasta reducers , suas ações Redux na pasta actions e definir um de nível superior arquivo index.js contendo sua armazenar e persistir lógica Se necessário, você pode até organizar os arquivos contidos nas duas pastas mencionadas em subpastas.

6. Camada de rota

Seu projeto pode já ter todas as suas rotas cobertas por seu aplicativo armazenadas em um arquivo routes.js . Definir um arquivo contendo todas as suas rotas para reuni-las em um só lugar e separá-las de quando são realmente usadas.

Novamente, para pequenos projetos, esta abordagem pode ser suficiente. O problema está no fato de que você não pode prever o tamanho do crescimento de seu aplicativo. É por isso que você deve definir uma camada projetada para conter todos os seus arquivos de roteamento e lógica. Um truque para dividir facilmente seu arquivo routes.js em muitos arquivos é criar um para cada um dos caminhos de roteamento de nível usados ​​por seu aplicativo.

Sa Camada de rota mple
Uma camada de rota de amostra composta por quatro arquivos.

7. Camada de utilidade

Este é o lugar para armazenar todas as funções de utilitário personalizadas das quais sua base de código depende. Embora você possa ter suas funções armazenadas em um único arquivo utilis.js , conforme o tamanho do seu projeto aumenta, você pode ser forçado a dividi-lo em vários arquivos.

É por isso que ter uma camada dedicada para isso pode se tornar inevitável. Em vez de esperar que isso ocorra, saia na frente do jogo e construa uma nova camada da seguinte maneira:

Dividindo arquivo inicial
Dividindo um iniciando o arquivo utils.js em dois arquivos diferentes.

8. Camada de visualização

Esta é a camada superior onde você armazenará todas as páginas em que seus aplicativos consistem. Observe que esta é a única camada que pode exigir arquivos importados de qualquer outra camada mencionada anteriormente.

Caso seu projeto tenha uma grande quantidade de páginas, você deve organizá-las em subpastas. Um bom critério para conseguir isso é replicar a estrutura de roteamento, assim como você faria em um projeto PHP. Por exemplo, todas as páginas que compartilham o https://yourdomain.dom/users/ o caminho básico deve ser colocado na pasta Usuários .

Sample View Layer Structure
Uma amostra de estrutura de camada de visualização com o critério apresentado o exemplo.

Arquivos restantes em sua estrutura de várias camadas

Lembre-se de que tal arquitetura pode não ser suficiente para cobrir todos os arquivos que compõem sua base de código. É por isso que sempre haverá arquivos adicionais que você pode não saber onde colocar.

Seguir uma estrutura tão organizada permite reduzi-los a alguns lugares. Uma boa regra prática é que, se você tiver menos de três arquivos, deve deixá-los na pasta de nível superior do seu projeto ou onde acha que eles pertencem. Caso contrário, você sempre pode projetar novas camadas que atendam às suas necessidades.

Conclusão

Neste artigo, vimos como (e por que você deve) organizar um projeto React para torná-lo mais eficiente. Ao colocar seus arquivos em pastas que representam uma arquitetura em várias camadas, você pode transformar seu projeto em uma estrutura muito mais organizada.

Com essa abordagem, cada arquivo terá seu próprio lugar. Isso permitirá que você e sua equipe definam padrões de arquitetura, torne toda a sua base de código mais robusta e sustentável e simplifique seu processo de desenvolvimento.

Obrigado por ler! Espero que você tenha achado este artigo útil. Sinta-se à vontade para entrar em contato comigo se tiver perguntas, comentários ou sugestões.

A postagem Aplicativos Optimize React usando um multi-estrutura em camadas apareceu primeiro no LogRocket Blog .