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

写在最后面

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

为了进步大家的浏览体验,对语句的构造和内容略有调整。如果发现本文中有存在瑕疵的中央,或者你有任何意见或者倡议,能够在评论区留言,或者加我的微信:code_maomao,欢送互相沟通交流学习。

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

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

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

从实质上讲,网络依然是将文档链接在一起的媒介。在网络浏览器中,每个页面都是HTML,带有CSS(用于款式设置)和JavaScript(用于加强性能)。明天,咱们应用这些技术来构建从集体博客和小型手册站点到简单的交互式应用程序的所有内容。其基本长处是Web提供了通用拜访权限。任何人只须要一个能够连贯网络的网络浏览器,会创立一个默认的环境。

咱们正在构建什么

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

在咱们的Web应用程序中:

  • 用户将可能创立笔记、浏览、更新和删除他们创立的笔记。
  • 用户将可能查看其余用户创立的笔记的摘要,并浏览其他人创立的单个笔记,只管他们将无奈更新或删除它们。
  • 用户将可能创立帐户,登录和登记。
  • 用户将可能检索其个人资料信息以及其余用户的公共个人资料信息。
  • 用户将可能珍藏其余用户的笔记以及检索其收藏夹列表。

这些性能将波及很多畛域,然而在本书的这一部分中,咱们将把它们分成小块。一旦学会了应用所有这些性能构建React应用程序,就能够将工具和技术利用于构建各种富Web应用程序。

咱们将如何构建它

你可能曾经猜到了,要构建此应用程序,咱们将应用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 titledocument.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 titledocument.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 dependenciesimport React from 'react';import { BrowserRouter as Router, Route } from 'react-router-dom';// import routesimport Home from './home';import MyNotes from './mynotes';import Favorites from './favorites';// define routesconst 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 routesimport 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-routerimport { 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向应用程序增加布局和款式。

如果有了解不到位的中央,欢送大家纠错。如果感觉还能够,麻烦您点赞珍藏或者分享一下,心愿能够帮到更多人。