Hoje, chamamos a atenção para a primeira parte da tradução do material, dedicada ao desenvolvimento de aplicações React em larga escala. Ao criar um aplicativo de uma página usando o React, é muito fácil alterar sua base de códigos. Isso complica a depuração do aplicativo, dificulta a atualização ou a extensão do código do projeto.

Existem muitas boas bibliotecas no ecossistema React que podem ser usadas para gerenciar certos aspectos de um aplicativo. Vamos abordar alguns deles em alguns detalhes. Além disso, algumas recomendações práticas serão fornecidas aqui. Se o projeto for bem dimensionado, será útil seguir essas recomendações desde o início dos trabalhos nele. Nesta parte da tradução, falaremos sobre planejamento, ações, fontes de dados e a API. O primeiro passo no desenvolvimento de aplicativos React em larga escala, que examinaremos, é o planejamento.
Parte 1:
Diretrizes práticas para o desenvolvimento de aplicativos React em larga escala. Planejamento, ações, fontes de dados e APIsParte 2:
Diretrizes práticas para o desenvolvimento de aplicativos React em larga escala. Parte 2: gerenciamento de estado, roteamentoPlanejamento
Na maioria das vezes, os desenvolvedores pulam essa etapa do trabalho no aplicativo. Isso se deve ao fato de que durante o processo de planejamento, nenhum trabalho é feito na escrita do código. Mas a importância desse passo não pode ser subestimada. Você aprenderá em breve por que isso é assim.
HyPor que você planeja desenvolver aplicativos?
O desenvolvimento de software requer a coordenação de muitos processos. Ao mesmo tempo, tudo é facilmente capaz de sair do controle. Obstáculos e incertezas encontrados no processo de desenvolvimento podem comprometer o cronograma do projeto.
Ajudar a cumprir os prazos é onde a fase de planejamento do projeto pode ajudá-lo. Nesse estágio, “coloque nas prateleiras” todos os recursos que o aplicativo deve ter. É muito mais fácil prever quanto tempo levará para criar pequenos módulos individuais, cuja lista está dos programadores, do que tentar, em mente, estimar o tempo do desenvolvimento de todo o projeto.
Se vários programadores participam de um grande projeto (como normalmente acontece), a presença de um plano pré-desenvolvido, um determinado documento, facilitará bastante a interação entre eles. De fato, várias tarefas formuladas neste documento podem ser atribuídas a desenvolvedores individuais. Sua presença ajudará os membros da equipe a conhecer o que seus colegas estão fazendo.
E finalmente, graças a este documento, você pode ver claramente como o trabalho no projeto está progredindo. Os programadores geralmente passam de trabalhar em uma parte do aplicativo para outra e retornam ao que fizeram antes, muito mais tarde do que gostariam.
Considere o processo de planejamento de aplicativos.
1Etapa 1: páginas e componentes
É necessário determinar a aparência e a funcionalidade de cada página do aplicativo. Uma das melhores abordagens aqui é desenhar cada página. Você pode fazer isso usando a
ferramenta de maquete , ou manualmente, no papel. Isso lhe dará uma boa compreensão de quais informações devem estar presentes em cada página. Aqui está a aparência de um layout de página.
Layout da página (extraído daqui )No layout acima, você pode identificar facilmente as entidades do contêiner pai e seus filhos. Posteriormente, os contêineres pai se tornarão as páginas do aplicativo e elementos menores cairão na pasta de
components
do projeto. Depois de concluir os layouts de desenho - escreva em cada um deles os nomes de páginas e componentes.
Etapa 2: ações e eventos
Depois de decidir sobre os componentes do aplicativo, pense em quais ações serão executadas em cada um deles. Posteriormente, a partir desses componentes, essas ações serão enviadas.
Considere uma loja on-line na página inicial da qual exibe uma lista de produtos recomendados. Cada um dos elementos desta lista será apresentado no projeto como um componente separado. Deixe o nome deste componente ser
ListItem
.
Um exemplo de uma página inicial da loja online (retirada daqui )Nesse aplicativo, a ação que o componente na seção
Product
getItems
é denominada
getItems
. Algumas outras atividades que podem ser incluídas nesta página podem incluir
getUserDetails
,
getSearchResults
e assim por diante.
Etapa 3: dados e modelos
Existem alguns dados associados a cada componente do aplicativo. Se os mesmos dados forem usados por vários componentes do aplicativo, eles farão parte de uma árvore de estados centralizada. A árvore de estado é gerenciada usando o
Redux .
Esses dados são usados por muitos componentes. Como resultado, quando os dados são alterados por um componente, eles são refletidos em outros componentes.
Crie uma lista de dados semelhantes para o seu aplicativo. Ele se tornará um diagrama de modelo. Com base nesta lista, será possível criar redutores.
products: { productId: {productId, productName, category, image, price}, productId: {productId, productName, category, image, price}, productId: {productId, productName, category, image, price}, }
Voltemos ao exemplo acima com uma loja online. A seção de produtos e novos produtos recomendados usa o mesmo tipo de dados usado para representar produtos individuais (algo como
product
). Esse tipo servirá de base para a criação de um dos redutores de aplicativos.
Depois de documentar o plano de ação, é hora de considerar alguns dos detalhes necessários para configurar a camada de aplicativo responsável por trabalhar com os dados.
Ações, fontes de dados e APIs
À medida que seu aplicativo cresce, muitas vezes acontece que um número excessivo de métodos está associado ao repositório Redux. Acontece que a estrutura de diretórios piora, afastando-se das reais necessidades do aplicativo. Tudo isso se torna difícil de manter, adicionando novos recursos ao aplicativo se torna mais complicado.
Vamos falar sobre como você pode ajustar algumas coisas para manter o código do repositório Redux limpo a longo prazo. Muitos problemas podem ser evitados se, desde o início, os módulos forem feitos para serem adequados para reutilização. Vale a pena fazer exatamente isso, mesmo que a princípio possa parecer um excesso, complicando desnecessariamente o projeto.
Design Design de API e aplicativos clientes
Durante a configuração inicial do armazenamento, o formato dos dados provenientes da API afeta muito a estrutura do armazenamento. Frequentemente, os dados devem ser convertidos antes de serem transferidos para redutores.
Recentemente,
muito foi dito sobre o que é necessário e o que não precisa ser feito ao projetar uma API. Fatores como a estrutura de back-end e o tamanho do aplicativo têm um impacto adicional em como as APIs são projetadas.
É recomendável, como no desenvolvimento de aplicativos de servidor, armazenar funções auxiliares em uma pasta separada. Podem ser, por exemplo, funções para formatar e mapear dados. Verifique se essas funções não têm efeitos colaterais (consulte
este artigo sobre funções puras).
export function formatTweet (tweet, author, authedUser, parentTweet) { const { id, likes, replies, text, timestamp } = tweet const { name, avatarURL } = author return { name, id, timestamp, text, avatar: avatarURL, likes: likes.length, replies: replies.length, hasLiked: likes.includes(authedUser), parent: !parentTweet ? null : { author: parentTweet.author, id: parentTweet.id, }
Neste exemplo de código, a função
formatTweet
adiciona uma nova chave (
parent
) ao objeto de tweet do aplicativo front-end. Essa função retorna dados com base nos parâmetros passados a ela, sem afetar os dados externos.
Aqui você pode ir ainda mais longe, mapeando dados para um objeto descrito anteriormente cuja estrutura corresponde às necessidades do seu aplicativo front-end. No entanto, você pode validar algumas chaves.
Agora vamos falar sobre as partes dos aplicativos responsáveis por fazer chamadas para a
API .
▍ Organização do trabalho com fontes de dados
O que falaremos nesta seção será usado diretamente pelo Redux para modificar o estado do aplicativo. Dependendo do tamanho do aplicativo (e, além disso, do tempo que o programador possui), você pode abordar o design do data warehouse usando uma das duas abordagens a seguir:
- Sem o uso de um agente (correio).
- Usando agente.
▍ Projetando um repositório sem usar um agente
Com essa abordagem, durante a configuração do armazenamento, os mecanismos para executar solicitações
GET
,
POST
e
PUT
para cada modelo são criados separadamente.
Os componentes interagem com a API sem usar um agenteO diagrama anterior mostra que cada componente envia ações que invocam métodos de diferentes armazenamentos de dados. Veja como, com essa abordagem, o método
BlogApi
arquivo
BlogApi
será
BlogApi
:
function updateBlog(blog){ let blog_object = new BlogModel(blog) axios.put('/blog', { ...blog_object }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); }
Essa abordagem economiza tempo ... E, a princípio, também permite que você faça alterações no código sem se preocupar com efeitos colaterais. Mas, por causa disso, o projeto terá uma grande quantidade de código redundante. Além disso, executar operações em grupos de objetos exigirá muito tempo.
▍ Projetando um repositório usando um agente
Com essa abordagem, no longo prazo, o projeto é mais fácil de manter, é mais fácil fazer alterações. A base de código não é poluída ao longo do tempo, pois o desenvolvedor é poupado do problema de executar consultas paralelas usando axios.
Os componentes interagem com a API usando um agenteNo entanto, com essa abordagem, é necessária uma certa quantidade de tempo para a configuração inicial do sistema. Ela é menos flexível. Isso é bom e ruim, pois não permite que o desenvolvedor faça algo incomum.
export default function courier(query, payload) { let path = `${SITE_URL}`; path += `/${query.model}`; if (query.id) path += `/${query.id}`; if (query.url) path += `/${query.url}`; if (query.var) path += `?${QueryString.stringify(query.var)}`; return axios({ url: path, ...payload }) .then(response => response) .catch(error => ({ error })); }
O código para o método de
courier
base é
courier
. Todos os manipuladores de API podem chamá-lo, passando os seguintes dados:
- Objeto de solicitação que contém informações relacionadas à URL. Por exemplo, o nome do modelo, a sequência de consultas e assim por diante.
- A carga útil que contém os cabeçalhos da solicitação e seu corpo.
Calls Chamadas de API e ações internas do aplicativo
Ao trabalhar com o Redux, é dada atenção especial ao uso de ações predefinidas. Isso torna previsíveis as alterações de dados no aplicativo.
Definir um monte de constantes em um aplicativo grande pode parecer uma tarefa impossível. No entanto, a implementação desta tarefa é bastante simplificada, graças à fase de planejamento que analisamos anteriormente.
export const BOOK_ACTIONS = { GET:'GET_BOOK', LIST:'GET_BOOKS', POST:'POST_BOOK', UPDATE:'UPDATE_BOOK', DELETE:'DELETE_BOOK', } export function createBook(book) { return { type: BOOK_ACTIONS.POST, book } export function handleCreateBook (book) { return (dispatch) => { return createBookAPI(book) .then(() => { dispatch(createBook(book)) }) .catch((e) => { console.warn('error in creating book', e); alert('Error Creating book') }) } export default { handleCreateBook, }
O trecho de código acima mostra uma maneira simples de usar os métodos de fonte de dados
createBookApi
com ações Redux. O método
createBook
pode ser facilmente transmitido para o método de
dispatch
Redux.
Além disso, observe que esse código está armazenado na pasta em que os arquivos de ação do projeto estão armazenados. Da mesma forma, você pode criar arquivos JavaScript que declarem ações e manipuladores para outros modelos de aplicativos.
Sumário
Hoje falamos sobre o papel da fase de planejamento no desenvolvimento de projetos de grande escala. Também discutimos aqui os recursos da organização do aplicativo com fontes de dados. A próxima parte deste artigo se concentrará no gerenciamento do estado de um aplicativo e no desenvolvimento de uma interface de usuário escalável.
Caros leitores! Onde você começa a desenvolver aplicativos React?
