翻译 | 《JavaScript Everywhere》第12章 使用React构建Web客户端

翻译 | 《JavaScript Everywhere》第12章 使用React构建Web客户端javascript

写在最前面

你们好呀,我是毛小悠,是一位前端开发工程师。正在翻译一本英文技术书籍。html

为了提升你们的阅读体验,对语句的结构和内容略有调整。若是发现本文中有存在瑕疵的地方,或者你有任何意见或者建议,能够在评论区留言,或者加个人微信:code_maomao,欢迎相互沟通交流学习。前端

(σ゚∀゚)σ..:*☆哎哟不错哦java

第12章 使用React构建Web客户端

超文本背后的原始想法是获取相关文档并将它们连接在一块儿:若是学术论文A引用学术论文B,让咱们能够轻松地单击某些内容并在它们之间导航。1989年,CERN的一位名为Tim Berners-Lee的软件工程师提出了将超文本与联网计算机相结合的想法,从而令人们能够轻松地创建这些链接,而无论文档的位置如何。每张猫的照片、新闻、推文、流媒体视频、求职网站和餐厅评论都应归功于全局连接文档的简单想法。react

从本质上讲,网络仍然是将文档连接在一块儿的媒介。在网络浏览器中,每一个页面都是HTML,带有CSS(用于样式设置)和JavaScript(用于加强功能)。今天,咱们使用这些技术来构建从我的博客和小型手册站点到复杂的交互式应用程序的全部内容。其根本优势是Web提供了通用访问权限。任何人只须要一个能够链接网络的网络浏览器,会建立一个默认的环境。git

咱们正在构建什么

在接下来的章节中,咱们将为社交笔记应用Notedly构建Web客户端。用户将可以建立和登陆账户,在Markdown中编写笔记,编辑他们的笔记,查看其余用户笔记的摘要以及“收藏”其余用户笔记。为此,咱们将与GraphQL服务器API进行交互。github

在咱们的Web应用程序中:web

  • 用户将可以建立笔记、阅读、更新和删除他们建立的笔记。
  • 用户将可以查看其余用户建立的笔记的摘要,并阅读其余人建立的单个笔记,尽管他们将没法更新或删除它们。
  • 用户将可以建立账户,登陆和注销。
  • 用户将可以检索其我的资料信息以及其余用户的公共我的资料信息。
  • 用户将可以收藏其余用户的笔记以及检索其收藏夹列表。

这些功能将涉及不少领域,可是在本书的这一部分中,咱们将把它们分红小块。一旦学会了使用全部这些功能构建React应用程序,就能够将工具和技术应用于构建各类富Web应用程序。npm

咱们将如何构建它

你可能已经猜到了,要构建此应用程序,咱们将使用React做为客户端JavaScript库。此外,咱们将从GraphQL API查询数据。为了帮助查询,修改和缓存数据,咱们将使用Apollo客户。Apollo Client包含用于使用GraphQL的一系列开源工具。咱们将使用库的React版本,可是Apollo的团队还开发了AngularVueScala.jsNative iOSNative Android集成。后端

其余GraphQL客户端库

尽管咱们将在本书中使用Apollo,但它远远不是惟一一个GraphQL客户端选项。FacebookRelayFormiddableurql也是两个受欢迎的选择。

此外,咱们将使用parcel做为咱们的代码捆绑器。代码捆绑器使咱们可使用Web浏览器中可能不具有的功能(例如,较新的语言功能,代码模块,压缩)编写JavaScript,并将其打包以供在浏览器环境中使用。ParcelWebpack等应用程序构建工具的无配置替代方案。它提供了许多不错的功能,例如代码拆分和在开发过程当中自动更新浏览器(又称热模块替换),而无需创建构建。如上一章所述,create-react-app它还提供了零配置的初始设置,在后台使用Webpack,但Parcel容许咱们从头开始构建应用程序,这是我发现学习的理想方式。

入门

在开始开发以前,咱们须要将项目启动代码文件复制到咱们的电脑上。

项目的源代码包含咱们开发应用程序所需的全部脚本和对第三方库的引用。要将代码克隆到本地计算机,请打开终端,导航到保存项目的目录,而后git clone项目存储库。若是你已经遍历了API章节,则可能已经建立了一个notedly目录来保持项目代码的条理性:

# change into the Projects directory
$ cd
$ cd Projects
$ # type the `mkdir notedly` command if you don't yet have a notedly directory
$ cd notedly
$ git clone git@github.com:javascripteverywhere/web.git
$ cd web
$ npm install

安装第三方依赖项

经过使用本书的入门代码的副本并在目录中运行npm install,你无需为任何第三方依赖项再次运行npm install

该代码的结构以下:

  • /src

这是你随书一块儿进行开发的目录。

  • /solutions

该目录包含每章的解决方案。若是你卡住了,这些能够供你参考。

  • /final

该目录包含最终的工做项目。

如今,你已经在电脑上安装了代码,复制项目的.env文件。这个文件保存了咱们特殊的工做环境变量。

例如,在本地工做时,咱们将指向API的本地实例,可是在部署应用程序时,咱们将指向咱们远程的API。复制.env文件,从Web目录在终端中键入如下内容:

$ cp .env.example .env

你如今应该看到一个.env文件。你无需对该文件作任何事情,可是随着API后端的开发,咱们将向其中添加信息。项目附带的.gitignore文件将确保你不会无心间提交.env文件。

求助,我看不到.env文件!

默认状况下,操做系统隐藏以句点开头的文件,由于这些文件一般由系统使用,而不是最终用户使用。若是看不到.env文件,请尝试在文本编辑器中打开目录。该文件应该在编辑器的文件浏览器中可见。或者,在终端窗口中键入ls -a将列出当前工做目录中的文件。

构建Web应用程序

在本地克隆了启动代码以后,咱们就能够构建React Web应用程序了。首先让咱们看一下src/index.html文件。这看起来像一个标准的但彻底为空的HTML文件,但请注意如下两行:

<div id="root"></div>
<script src="./App.js"></script>

这两行对咱们的React应用程序很是重要。

root将提供整个应用程序的容器。同时,App.js文件将成为咱们JavaScript应用程序的入口。

如今咱们能够开始在src/App.js文件中开发React应用程序了。若是你跟随上一章中的React简介,可能会以为很熟悉。在src/App.js中,咱们首先导入reactreact-dom库:

import React from 'react';
import ReactDOM from 'react-dom';

如今,咱们将建立一个名为App的函数,该函数将返回应用程序的内容。如今,这将只是元素中包含的两行HTML

const App = () => {
return (
<div>
<h1>Hello Notedly!</h1>
<p>Welcome to the Notedly application</p>
</div>
);
};

和全部的div相关的是什么?

若是你只是从React入手,你可能会想知道用标签包围组件的趋势。React的组件必须包含于父元素,这每每是一种标签,但也能够是任何其余适当的HTML标签,例如,,或.

若是感受包含HTML的标记多余,咱们能够用空的<>标记在咱们的JavaScript代码中包含这些组件。

最后,咱们将经过添加如下内容来指示React在根IDroot的元素内渲染应用程序:

ReactDOM.render(<App />, document.getElementById('root'));

如今,咱们的src/App.js文件的完整内容应为:

import React from 'react';
import ReactDOM from 'react-dom';
const App = () => {
return (
<div>
<h1>Hello Notedly!</h1>
<p>Welcome to the Notedly application</p>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('root'));

完成此操做后,让咱们在Web浏览器中进行查看。经过在终端应用程序中键入npm run dev来启动本地开发服务器。编译代码后,请访问 http://localhost:1234来查看页面(图12-1)。

12-1咱们最初在浏览器中运行的React应用程序

路由

网络的定义特征之一是可以将文档连接在一块儿。一样,对于咱们的应用程序,咱们但愿用户可以在屏幕或页面之间导航。在HTML呈现的应用程序中,这将涉及建立多个HTML文档。每当用户导航到新文档时,即便两个页面上存在共享的方面(例如页眉或页脚),整个文档也会从新加载。

JavaScript应用程序中,咱们能够利用客户端路由。在许多方面,这将相似于HTML连接。用户将单击一个连接,URL将更新,而且他们将导航到新屏幕。不一样之处在于咱们的应用程序只会使用更改后的内容来更新页面。体验将是“相似于应用程序的”的流畅,这意味着将不会看到页面的刷新。

React中,最经常使用的路由库是Router。这个库使咱们可以向React Web应用程序添加路由功能。为了将路由引入咱们的应用程序,让咱们首先建立一个src/pages目录并添加如下文件:

  • /src/pages/index.js
  • /src/pages/home.js
  • /src/pages/mynotes.js
  • /src/pages/favorites.js

咱们的home.jsmynotes.jsfavorite.js文件将成为咱们单独的页面组件。咱们能够为每一个文件建立一些初始内容和效果钩子,当用户导航到页面时,它们将更新文档标题。

src/pages/home.js中:

import React from 'react';
const Home = () => {
return (
<div>
<h1>Notedly</h1>
<p>This is the home page</p>
</div>
);
};
export default Home;

src/pages/mynotes.js中:

import React, { useEffect } from 'react';
const MyNotes = () => {
useEffect(() => {
// update the document title
document.title = 'My Notes — Notedly';
});
return (
<div>
<h1>Notedly</h1>
<p>These are my notes</p>
</div>
);
};
export default MyNotes;

src/pages/favorites.js中:

import React, { useEffect } from 'react';
const Favorites = () => {
useEffect(() => {
// update the document title
document.title = 'Favorites — Notedly';
});
return (
<div>
<h1>Notedly</h1>
<p>These are my favorites</p>
</div>
);
};
export default Favorites;

useEffect

在前面的示例中,咱们使用ReactuseEffect钩子来设置页面标题。Effect挂钩使咱们在组件中存在反作用,会更新与组件自己无关的内容。若是你有兴趣,能够深刻探讨ReactEffect hooks文档。

如今,在src/pages/index.js中,咱们将使用react-router-dom包导入React RouterWeb浏览器路由所需的方法:

import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';

接下来,咱们将导入刚刚建立的页面组件:

import Home from './home';
import MyNotes from './mynotes';
import Favorites from './favorites';

最后,咱们将使用特定的URL指定咱们建立为路由的每一个页面组件。请注意,对于咱们的“Home”路由使用了彻底匹配,这将确保仅针对根URL呈现主页组件:

const Pages = () => {
return (
<Router>
<Route exact path="/" component={Home} />
<Route path="/mynotes" component={MyNotes} />
<Route path="/favorites" component={Favorites} />
</Router>
);
};
export default Pages;

如今,咱们完整的src/pages/index.js文件应以下所示:

// import React and routing dependencies
import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
// import routes
import Home from './home';
import MyNotes from './mynotes';
import Favorites from './favorites';
// define routes
const Pages = () => {
return (
<Router>
<Route exact path="/" component={Home} />
<Route path="/mynotes" component={MyNotes} />
<Route path="/favorites" component={Favorites} />
</Router>
);
};
export default Pages;

最后,咱们能够经过导入路由并渲染组件来更新src/App.js文件以使用咱们的路由:

import React from 'react';
import ReactDOM from 'react-dom';
// import routes
import Pages from '/pages';
const App = () => {
return (
<div>
<Pages />
</div>
);
};
ReactDOM.render(<App />, document.getElementById('root'));

如今,若是你在Web浏览器中手动更新URL,则应该可以查看每一个组件。例如,键入http:// localhost:1234/favorites来呈现“收藏夹”页面。

连接

咱们已经建立了页面,可是缺乏将它们连接在一块儿的关键部分。所以,让咱们从首页添加到其余页面的连接。为此,咱们将使用React RouterLink组件。

src/pages/home.js中:

import React from 'react';
// import the Link component from react-router
import { Link } from 'react-router-dom';
const Home = () => {
return (
<div>
<h1>Notedly</h1>
<p>This is the home page</p>
{ /* add a list of links */ }
<ul>
<li>
<Link to="/mynotes">My Notes</Link>
</li>
<li>
<Link to="/favorites">Favorites</Link>
</li>
</ul>
</div>
);
};
export default Home;

这样咱们就能够浏览咱们的应用程序。
单击主页上的连接之一将导航到相应的页面组件。
浏览器的核心导航功能(如后退和前进按钮)也将继续起做用。

UI组件

咱们已经成功建立了单个页面组件,而且能够在它们之间进行导航。在构建页面时,它们将具备几个共享的用户界面元素,例如标题和站点范围的导航。每次使用它们时重写它们都不会很是高效(而且会很烦人)。取而代之的是,咱们能够编写可重用的接口组件,并将它们导入到咱们须要的任何地方。实际上,将咱们的UI视为由微小的组件组成是React的核心功能之一,也是我在掌握框架方面的突破。

咱们将从为应用程序建立标题和导航组件开始。首先,让咱们在src目录中建立一个名为components的新目录。在src/components目录中,咱们将建立两个名为Header.jsNavigation.js的新文件。React组件必须大写,所以咱们也将遵循大写文件名的惯例。

让咱们首先在src/components/Header.js中编写标头组件。为此,咱们将导入logo.svg文件,并为咱们的组件添加相应的标记:

import React from 'react';
import logo from '../img/logo.svg';
const Header = () => {
return (
<header> <img src={logo} alt="Notedly Logo" height="40" /> <h1>Notedly</h1> </header> );
};
export default Header;

对于咱们的导航组件,咱们将导入React RouterLink功能并标记一个无序的连接列表。在src/components/Navigation.js中:

import React from 'react';
import { Link } from 'react-router-dom';
const Navigation = () => {
return (
<nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/mynotes">My Notes</Link> </li> <li> <Link to="/favorites">Favorites</Link> </li> </ul> </nav>
);
};
export default Navigation;

在屏幕截图中,你会发现我还包括了表情符号字符做为导航图标。

若是你要这样作,包含表情符号字符的可访问标记以下:

<span aria-hidden="true" role="img">
<!-- emoji character --> </span>

完成标题和导航组件后,咱们如今能够在应用程序中使用它们了。让咱们更新src/pages/home.js文件以包含这些组件。咱们将首先导入它们,而后将组件包括在咱们的JSX标记中。

咱们的src/pages/home.js如今将以下所示(图12-2):

import React from 'react';
import Header from '../components/Header';
import Navigation from '../components/Navigation';
const Home = () => {
return (
<div> <Header /> <Navigation /> <p>This is the home page</p> </div>
);
};
export default Home;

12-2使用React组件,咱们能够轻松地组合可共享的UI功能。

这是咱们可以在咱们的应用程序中建立可共享组件所需的一切。有关在UI中使用组件的更多信息,我强烈建议阅读React文档页““Thinking in React”.

结论

网络仍然是分发应用程序的无比重要的媒介。它使开发者能够实时更新访问。

在本章中,咱们在React中构建了JavaScript Web应用程序。在下一章中,咱们将使用React组件和CSS-in-JS向应用程序添加布局和样式。

若是有理解不到位的地方,欢迎你们纠错。若是以为还能够,麻烦您点赞收藏或者分享一下,但愿能够帮到更多人。

相关文章
相关标签/搜索