开发大型React应用程序的实用指南。 计划,操作,数据源和API

今天,我们提请您注意材料翻译的第一部分,该部分专门用于大规模React应用程序的开发。 使用React创建一页应用程序时,很容易弄乱其代码库。 这使应用程序的调试复杂化,使其难以更新或扩展项目代码。



React生态系统中有许多优秀的库可用于管理应用程序的某些方面。 我们将详细介绍其中一些。 另外,这里将给出一些实用的建议。 如果项目能够很好地进行扩展,那么从一开始就遵循这些建议将很有用。 在翻译的这一部分中,我们将讨论计划,操作,数据源和API。 我们将研究开发大规模React应用程序的第一步是计划。

第1部分: 开发大规模React应用程序的实用指南。 计划,操作,数据源和API

第2部分: 开发大规模React应用程序的实用指南。 第2部分:状态管理,路由


规划中


开发人员通常会跳过此应用程序的工作阶段。 这是由于在计划过程中没有编写代码的工作。 但是这一步骤的重要性不可低估。 您很快就会知道为什么会这样。

developing为什么开发应用程序时要计划?


软件开发需要许多过程的协调。 同时,一切都非常容易失控。 在开发过程中遇到的障碍和不确定性可能会危害项目的时间安排。

在项目计划阶段可以帮助您按时完成任务。 在此阶段,“搁置”应用程序应具有的所有功能。 相对于估计整个项目的开发时间,要容易得多。

如果几个程序员参与一个大型项目(通常会发生这种情况),那么预先制定的计划(某个文档)的存在将极大地促进他们彼此之间的交互。 实际上,可以将本文档中阐述的各种任务分配给各个开发人员。 它的存在将帮助团队成员了解他们的同事在做什么。

最后,借助此文档,您可以非常清楚地看到项目的工作进度。 程序员通常从处理应用程序的一部分转移到另一部分,然后返回到他们之前所做的工作,比他们想要的要晚得多。
考虑应用程序计划过程。

▍步骤1:页面和组件


有必要确定应用程序每个页面的外观和功能。 最好的方法之一是绘制每页。 您可以使用样机工具或手动在纸上进行此操作。 这将使您对每个页面上应显示的信息有很好的了解。 这是页面布局的外观。


页面布局( 从此处获取

在以上布局中,您可以轻松标识父容器实体及其子代。 以后,父容器将成为应用程序的页面,较小的元素将落入项目的components文件夹中。 完成图形布局后,在每个布局上写下页面和组件的名称。

▍步骤2:动作和事件


在确定了应用程序的组件之后,请考虑将在每个组件中执行哪些操作。 稍后,将从这些组件中发送这些操作。

考虑在主页上显示推荐产品列表的在线商店。 此列表的每个元素将在项目中作为单独的组件呈现。 让此组件的名称为ListItem


网上商店首页的示例( 从此处获取

在此应用程序中,“ Product部分中的组件执行的操作称为getItems 。 此页面上可能包括的其他一些活动可能包括getUserDetailsgetSearchResults等等。

▍步骤3:数据和模型


应用程序的每个组件都有一些数据。 如果几个应用程序组件使用相同的数据,则它们将成为集中式状态树的一部分。 使用Redux管理状态树。

该数据被许多组件使用。 结果,当数据由一个组件更改时,它会反映在其他组件中。

为您的应用程序创建类似数据的列表。 它将成为模型图。 基于此列表,可以创建减速器。

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

让我们回到上面的在线商店示例。 “推荐产品”和“新产品”部分使用与表示单个产品(类似product )相同的数据类型。 此类型将用作创建应用程序简化程序之一的基础。

在记录了行动计划之后,是时候考虑设置负责处理数据的应用层所需的一些细节了。

动作,数据源和API


随着应用程序的增长,经常会发生与Redux存储库关联的方法过多的情况。 碰巧目录结构恶化了,从而脱离了应用程序的实际需求。 所有这些都变得难以维护,向应用程序添加新功能变得更加复杂。

让我们谈谈如何调整某些事情以长期保持Redux存储库代码的干净。 如果从一开始就使模块适合于重用,则可以避免许多问题。 这样做是值得的,尽管起初看起来有些多余,但不必要地使项目复杂化。

▍API设计和客户端应用程序


在存储库的初始设置期间,来自API的数据格式极大地影响了存储库的结构。 通常,必须先转换数据,然后才能将其传输到减速器。

最近,关于设计API时需要做什么和不需要做什么的话题已经很多。 后端框架和应用程序大小等因素对API的设计有额外的影响。

与开发服务器应用程序一样,建议将辅助功能存储在单独的文件夹中。 这些可以是例如用于格式化和映射数据的功能。 确保这些功能没有副作用(请参阅有关纯功能的本文)。

 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,    } 

在此代码示例中, formatTweet函数将新密钥( parent )添加到前端应用程序的tweet对象。 此函数根据传递给它的参数返回数据,而不影响其外部的数据。

在这里,您可以通过将数据映射到先前描述的对象而走得更远,该对象的结构与您的前端应用程序的需求相对应。 但是,您可以验证一些密钥。

现在,让我们谈谈应用程序中负责调用API的那些部分。

▍整理数据来源的工作


Redux将在本节中讨论的内容直接用于修改应用程序的状态。 根据应用程序的大小(以及程序员的时间),可以使用以下两种方法之一来进行数据仓库的设计:

  • 无需使用代理(快递)。
  • 使用代理。

without在不使用代理的情况下设计存储库


使用这种方法,在存储配置期间,将分别创建用于执行每个模型的GETPOSTPUT请求的机制。


组件无需使用代理即可与API交互

上图显示了每个组件发送的动作将调用来自不同数据存储区的方法。 通过这种方法, BlogApi文件中的updateBlog方法如下所示:

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

这种方法节省了时间...首先,它还使您可以更改代码而不必担心副作用。 但是正因为如此,该项目将具有大量的冗余代码。 另外,对对象组执行操作将需要大量时间。

using使用代理设计存储库


使用这种方法,从长远来看,项目更易于维护,更容易进行更改。 随着开发人员免于使用axios执行并行查询的麻烦,代码库不会随着时间的流逝而受到污染。


组件使用代理与API进行交互

但是,使用这种方法,系统的初始设置需要一定的时间。 她不太灵活。 这是好事,也是坏事,因为它不允许开发人员执行异常操作。

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

基本courier方法的代码courier 。 所有API处理程序都可以调用它,并向其传递以下数据:

  • 请求对象包含与URL相关的信息。 例如,模型名称,查询字符串等。
  • 包含请求标头及其主体的有效负载。

▍API调用和应用程序内部动作


使用Redux时,要特别注意使用预定义的操作。 这样可以预测应用程序中发生的数据更改。

在大型应用程序中定义一堆常量似乎是不可能完成的任务。 但是,由于我们先前已审查了计划阶段,因此大大简化了此任务的执行。

 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, } 

上面的代码段显示了一种将createBookApi数据源方法与Redux操作一起使用的简单方法。 createBook方法可以轻松地传递给Redux dispatch方法。

此外,请注意,此代码存储在存储项目操作文件的文件夹中。 同样,您可以创建JavaScript文件来声明其他应用程序模型的操作和处理程序。

总结


今天,我们讨论了规划阶段在大型项目开发中的作用。 我们还在这里讨论了带有数据源的应用程序组织的功能。 本文的下一部分将集中于管理应用程序的状态和开发可伸缩的用户界面。

亲爱的读者们! 您从哪里开始开发React应用程序?

Source: https://habr.com/ru/post/zh-CN458496/


All Articles