Directrices prácticas para desarrollar aplicaciones React a gran escala. Planificación, acciones, orígenes de datos y API

Hoy llamamos su atención sobre la primera parte de la traducción del material, dedicada al desarrollo de aplicaciones React a gran escala. Al crear una aplicación de una página con React, es muy fácil desordenar su base de código. Esto complica la depuración de la aplicación, dificulta la actualización o extensión del código del proyecto.



Hay muchas buenas bibliotecas en el ecosistema React que se pueden usar para administrar ciertos aspectos de una aplicación. Nos detendremos en algunos de ellos con cierto detalle. Además, aquí se darán algunas recomendaciones prácticas. Si el proyecto debe escalar bien, será útil seguir estas recomendaciones desde el comienzo del trabajo en él. En esta parte de la traducción, hablaremos sobre planificación, acciones, fuentes de datos y la API. El primer paso en el desarrollo de aplicaciones React a gran escala, que veremos, es la planificación.

Parte 1: Pautas prácticas para desarrollar aplicaciones React a gran escala. Planificación, acciones, orígenes de datos y API

Parte 2: Pautas prácticas para desarrollar aplicaciones React a gran escala. Parte 2: gestión del estado, enrutamiento


Planificacion


Muy a menudo, los desarrolladores omiten esta etapa de trabajo en la aplicación. Esto se debe al hecho de que durante el proceso de planificación no se realiza ningún trabajo para escribir el código. Pero la importancia de este paso no puede subestimarse. Pronto aprenderá por qué es así.

▍ ¿Por qué planeas desarrollar aplicaciones?


El desarrollo de software requiere la coordinación de muchos procesos. Al mismo tiempo, todo es muy fácil de perder. Los obstáculos e incertidumbres encontrados en el proceso de desarrollo pueden poner en peligro el momento del proyecto.

Ayudar a cumplir con los plazos es donde la fase de planificación del proyecto puede ayudarlo. En esta etapa, "poner en los estantes" todas las características que la aplicación debe tener. Es mucho más fácil predecir cuánto tiempo llevará crear pequeños módulos individuales, cuya lista corresponde a los programadores, que intentar, en mente, estimar el momento del desarrollo de todo el proyecto.

Si varios programadores participan en un gran proyecto (como suele suceder), la presencia de un plan previamente desarrollado, un cierto documento, facilitará enormemente su interacción entre ellos. De hecho, varias tareas formuladas en este documento pueden asignarse a desarrolladores individuales. Su presencia ayudará a los miembros del equipo a estar al tanto de lo que están haciendo sus colegas.

Y finalmente, gracias a este documento, puede ver muy claramente cómo progresa el trabajo en el proyecto. Los programadores a menudo pasan de trabajar en una parte de la aplicación a otra y regresan a lo que hicieron antes, mucho más tarde de lo que quisieran.
Considere el proceso de planificación de la aplicación.

▍Paso 1: páginas y componentes


Es necesario determinar el aspecto y la funcionalidad de cada página de la aplicación. Uno de los mejores enfoques aquí es dibujar cada página. Puede hacerlo utilizando la herramienta de maqueta , o manualmente, en papel. Esto le dará una buena comprensión de qué información debe estar presente en cada página. Así es como se vería un diseño de página.


Diseño de página (tomado de aquí )

En el diseño anterior, puede identificar fácilmente las entidades del contenedor principal y sus elementos secundarios. Más tarde, los contenedores principales se convertirán en las páginas de la aplicación y los elementos más pequeños caerán en la carpeta de components del proyecto. Una vez que haya terminado de dibujar los diseños, escriba en cada uno de ellos los nombres de las páginas y los componentes.

▍Paso 2: acciones y eventos


Una vez que haya decidido los componentes de la aplicación, piense qué acciones se realizarán en cada uno de ellos. Más tarde, desde estos componentes, se enviarán estas acciones.

Considere una tienda en línea en la página de inicio que muestra una lista de productos recomendados. Cada uno de los elementos de esta lista se presentará en el proyecto como un componente separado. Deje que el nombre de este componente sea ListItem .


Un ejemplo de la página de inicio de una tienda en línea (tomada de aquí )

En esta aplicación, la acción que realiza el componente en la sección Product se llama getItems . Algunas otras actividades que pueden incluirse en esta página pueden incluir getUserDetails , getSearchResults , etc.

▍Paso 3: datos y modelos


Hay algunos datos asociados con cada componente de la aplicación. Si varios componentes de la aplicación utilizan los mismos datos, serán parte de un árbol de estado centralizado. El árbol de estado se gestiona con Redux .

Estos datos son utilizados por muchos componentes. Como resultado, cuando un componente cambia los datos, se refleja en otros componentes.

Cree una lista de datos similares para su aplicación. Se convertirá en un diagrama modelo. Según esta lista, será posible crear reductores.

 products: {  productId: {productId, productName, category, image, price},  productId: {productId, productName, category, image, price},  productId: {productId, productName, category, image, price}, } 

Volvamos al ejemplo anterior con una tienda en línea. La sección de productos recomendados y productos nuevos utiliza el mismo tipo de datos utilizado para representar productos individuales (algo así como un product ). Este tipo servirá como base para crear uno de los reductores de aplicaciones.

Después de documentar el plan de acción, es hora de considerar algunos de los detalles necesarios para configurar la capa de aplicación responsable de trabajar con los datos.

Acciones, orígenes de datos y API


A medida que su aplicación crece, a menudo sucede que hay una cantidad excesiva de métodos asociados con el repositorio de Redux. Sucede que la estructura del directorio empeora, alejándose de las necesidades reales de la aplicación. Todo esto se vuelve difícil de mantener, agregar nuevas características a la aplicación se vuelve más complicado.

Hablemos sobre cómo puede ajustar algunas cosas para mantener limpio el código del repositorio de Redux a largo plazo. Se pueden evitar muchos problemas si, desde el principio, los módulos están diseñados para ser reutilizados. Vale la pena hacer eso, aunque al principio parezca un exceso, complicando innecesariamente el proyecto.

▍ Diseño de API y aplicaciones de cliente


Durante la configuración inicial del almacenamiento, el formato de los datos que provienen de la API afecta en gran medida la estructura del almacenamiento. A menudo, los datos deben convertirse antes de poder transferirse a los reductores.

Recientemente, se ha dicho mucho sobre lo que se necesita y lo que no se debe hacer al diseñar una API. Factores como el marco de back-end y el tamaño de la aplicación tienen un impacto adicional en cómo se diseñan las API.

Se recomienda, como en el desarrollo de aplicaciones de servidor, almacenar funciones auxiliares en una carpeta separada. Estas pueden ser, por ejemplo, funciones para formatear y mapear datos. Asegúrese de que estas funciones no tengan efectos secundarios (consulte este artículo sobre funciones 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,    } 

En este ejemplo de código, la función formatTweet agrega una nueva clave ( parent ) al objeto de tweet de la aplicación front-end. Esta función devuelve datos basados ​​en los parámetros que se le pasan, sin afectar los datos externos.

Aquí puede ir aún más lejos asignando datos a un objeto descrito anteriormente, cuya estructura corresponde a las necesidades de su aplicación front-end. Sin embargo, puede validar algunas claves.

Ahora hablemos de las partes de las aplicaciones que son responsables de realizar llamadas a la API .

▍ Organización del trabajo con fuentes de datos.


De lo que hablaremos en esta sección será utilizado directamente por Redux para modificar el estado de la aplicación. Dependiendo del tamaño de la aplicación (y, además, del tiempo que tenga el programador), puede abordar el diseño del almacén de datos utilizando uno de los siguientes dos enfoques:

  • Sin el uso de un agente (mensajero).
  • Usando agente.

▍ Diseñar un repositorio sin usar un agente


Con este enfoque, durante la configuración del almacenamiento, los mecanismos para ejecutar las POST GET , POST y PUT para cada modelo se crean por separado.


Los componentes interactúan con la API sin usar un agente

El diagrama anterior muestra que cada componente envía acciones que invocan métodos de diferentes almacenes de datos. Así es como, con este enfoque, se updateBlog método BlogApi archivo 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);  }); } 

Este enfoque ahorra tiempo ... Y al principio también le permite realizar cambios en el código sin preocuparse por los efectos secundarios. Pero debido a esto, el proyecto tendrá una gran cantidad de código redundante. Además, realizar operaciones en grupos de objetos requerirá mucho tiempo.

▍ Diseñar un repositorio usando un agente


Con este enfoque, a la larga, el proyecto es más fácil de mantener, es más fácil hacer cambios. La base del código no se contamina con el tiempo, ya que el desarrollador se ahorra el problema de ejecutar consultas paralelas utilizando axios.


Los componentes interactúan con la API usando un agente

Sin embargo, con este enfoque, se requiere una cierta cantidad de tiempo para la configuración inicial del sistema. Ella es menos flexible. Esto es bueno y malo, ya que no permite que el desarrollador haga algo inusual.

 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 })); } 

El código para el método de courier base se courier . Todos los manejadores de API pueden llamarlo, pasándole los siguientes datos:

  • Solicitar objeto que contenga información relacionada con URL. Por ejemplo, el nombre del modelo, la cadena de consulta, etc.
  • La carga útil que contiene los encabezados de solicitud y su cuerpo.

▍ Llamadas API y acciones internas de la aplicación


Cuando se trabaja con Redux, se presta especial atención al uso de acciones predefinidas. Esto hace que los cambios de datos que ocurren en la aplicación sean predecibles.

Definir un montón de constantes en una aplicación grande puede parecer una tarea imposible. Sin embargo, la implementación de esta tarea se simplifica enormemente gracias a la fase de planificación que revisamos 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, } 

El fragmento de código anterior muestra una forma simple de usar los métodos de fuente de datos createBookApi con acciones de Redux. El método createBook se puede pasar fácilmente al método de dispatch Redux.

Además, tenga en cuenta que este código se almacena en la carpeta en la que se almacenan los archivos de acción del proyecto. Del mismo modo, puede crear archivos JavaScript que declaren acciones y controladores para otros modelos de aplicación.

Resumen


Hoy hablamos sobre el papel de la fase de planificación en el desarrollo de proyectos a gran escala. También discutimos aquí las características de la organización de la aplicación con fuentes de datos. La siguiente parte de este artículo se centrará en administrar el estado de una aplicación y desarrollar una interfaz de usuario escalable.

Estimados lectores! ¿Dónde comienzas a desarrollar aplicaciones React?

Source: https://habr.com/ru/post/458496/


All Articles