以下为译文:
最后这个项目的目标是要构建一个漂亮的单页应用,前端使用 React.js 和 Redux.js,调用 Ruby on Rails API。
单页应用
首先,什么是单页应用?单页应用就是一个 站或Web应用程序,根据用户的动作或行为,动态地改写当前页的内容,而不是从服务器加载全新的页面。实现途径有两种:
在一次页面加载中读取所有的页面内容。但考虑到应用程序的复杂性,这样做可能需要很长时间,因此会影响用户体验。
在某个用户事件后,向服务器请求相应的内容。常见的用户事件包括点击按钮、页面向下滚动、鼠标悬停在某个元素上、按下键盘上的某个键等。
对于复杂的应用程序,第二种方式更常见。毕竟,单页应用存在的原因就是它能提供更为平滑的用户体验,不会被全页重新加载打断。
从代码的角度来讲,单页应用意味着整个应用程序中只有一个HTML页面,通常这个页面名为index.html。
构建应用程序结构
应用程序分为两部分:前端和后端。前端是用户交互的部分,即用户界面。后端负责服务器与用户界面之间的连接。构建应用程序有两个选择:
第一个选择就是把前端和后端都放在同一个代码仓库中(比如GitHub上的代码仓库)。
上述两种方法并没有对错之分。基于上面给出的两个理由。我在构建应用程序时选择了使用两个独立的代码仓库、
第一个代码仓库是后端的。我在终端中使用下述命令创建了一个Rails应用程序作为API,不过没有任何视图。这跟创建普通的Rails应用程序是一样的,只不过多了一个参数。
至于前端,我采用了create-react-app生成器。
这两个命令可以帮我建好所需的一切文件。
关于组件的类型
该项目的技术要求是,至少需要写两个容器组件,以及5个无状态组件。React中的组件是界面的基本构成元素。它可以从父组件接受输入(通过props访问),还可以重用。
下面详细介绍一下容器组件和无状态组件。首先需要解释一下什么是状态(state)。状态就是可能会改变的数据。状态改变可能有多种原因,其中之一就是数据库更新导致状态变化,另一个原因就是用户修改了数据。
容器组件也称为有状态组件,而无状态组件也称为表现组件。容器组件和表现组件并没有严格的区分,每个开发者都可以按照自己的意愿来组织各个组件。但一般而言,容器组件是有状态的,可以通过其状态改变来跟踪,而表现组件没有状态,它可以显示传递过来的props,也可以永远显示固定的内容。
React中的路由
由于单页应用中不会重新加载完整的页面,因此产生的问题之一就是路由如何进行。Web应用程序中路由的作用是,在用户访问特定 页时确定需要执行什么。我们的单页应用中只有一个视图,因此没办法像Rails应用程序那样在用户点击链接时跳转到另一个视图。
凡事都有解决的办法,对于这个问题,我们可以使用react-router库。它有许多功能,其中包括:
URL显示用户的当前位置,而不仅仅是显示根页面的URL
用户可以使用浏览器的前进和后退按钮
用户可以在地址栏中输入URL,跳转到指定页面
下面以 CitiesContainer 为例来介绍路由的工作方式:
这里使用了 path 而不是 exact path,因此所有包含 /cities 的路径都会被处理。CitiesContainer 容器的内部如下:
React-router-dom 包为开发者提供了 routerProps。该属性可以将URL的内容作为参数传递给props。在这里,我们可以通过 props 访问城市的id,进而可以对 cities(通过props访问)进行过滤,找到我们需要的那个城市。
使用Redux
终于讲到了Redux。Redux是什么呢?这个问题我也问过自己,也问过Google。我在Youtube上找到了这个视频(https://www.youtube.com/watch?v=np8A_aW7Pew),介绍得非常清楚。我希望对你也有帮助。Redux的文档告诉我们,Redux是一个供 JavaScript 应用程序使用的、“可预测的”状态容器。文档中强调了Redux的4个方面:
可预测:它有助于编写在所有环境中行为都很一致的应用程序,更容易测试。
中心化:应用程序的状态和逻辑中心化,可以实现强大的功能,如状态持久化等。
可调式:Redux DevTools 可以非常方便地跟踪应用程序状态变化发生的时间、位置、原因以及方式等。
灵活:Redux可以与任何UI层结合使用。
在我们的应用程序中,Redux有许多便利之处,但最重要的一点是你可以从任何地方访问当前用户的信息(如果存在当前登录用户的话)。我们将用户信息保存到Redux存储中,就可以从应用程序的任意位置访问,而不仅限于将当前用户通过props传递的那些组件。实际上,任何子组件都可以通过以下两种方式之一连接到Redux存储:
使用mapsStateToProps,无需从组件中访问Redux存储,就能将状态内容放到props中
使用mapDispatchToProps,无需从组件中访问Redux存储,就能分发actions。
这样就可以分离状态管理和状态显示。但这并非Redux的全部功能。我们在构建异步action creator的时候还是用了thunk中间件。
什么是中间件?维基百科的解释是“提供系统软件和应用软件之间连接的软件,以便于软件各部件之间的沟通”。你可以认为中间件就像胶水一样。因此 thunk 可以让我们做一些原本做不到的事情。thunk 函数的参数是 dispatch,因此可以在函数中使用,在本例中就是在action creator中使用。由于dispatch可以在函数内使用,我们可以利用这一点,仅在fetch请求结束时进行分发。如下例所示,我们仅在获取所有城市的fetch请求结束后进行分发:
利用fetch实现数据持久化
我们可以通过fetch,用GET方式从服务器上获得数据,也可以用POST方式将数据发送到服务器。用GET获取数据的方式可以参照前面讨论路由的时候提到的 CitiesContainer 示例。我们在下面的action控制器中,利用fetch以GET方式获取所有城市:
在认证部分,登录action creator是一个以POST方式向服务器发送数据的例子:
至于样式,我最初的计划是使用React版的Bootstrap,因为这是唯一一个我听说过的库。在样式方面我还是新手,而且我没找到导航条,因此搜索了一下React中有什么可以使用的框架。然后在这篇文章(https://medium.com/@
zeolearn/6-best-reactjs-based-ui-frameworks-9c780b96236c)中看到了Semantic UI React的Menu组件,这正是我所需要的东西。我从来没有用过其他样式框架,因此没办法比较Semantic UI和其他组件哪个更容易使用,但我必须要说,Semantic UI非常容易上手。
样式并不是这个项目的重点,但我计划在这个应用程序中实现这个样式。我已经建立了基础结构和基本的功能,现在添加新功能已经比较容易了。我计划继续改进应用程序的功能。
原文:https://medium.com/@
annelaure.developer/my-first-full-stack-web-application-8ac82db61b10
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!