一、React 和 UI 设计简介

React 无疑是网络上谈论最多的图书馆之一。它的流行程度与 jQuery 的鼎盛时期一样,越来越多的开发人员选择它来构建 web 应用程序的用户界面。为什么它变得如此流行?为什么这个 JavaScript 库与其他库相比如此创新?

在这本书中,我们将通过展示图书馆提供的内容,并通过使用它来构建高效的 web 用户界面,试图为这些问题提供答案。

在本章中,我们将介绍 React,并开始构建基于 React 的应用程序的基本基础架构。然后,我们将分析如何设计一个用户界面,以便它可以很容易地映射到 React 组件,从而充分利用 React 内部架构的优点。

在本章结束时,您将能够:

  • 描述 React 是什么以及它在应用程序开发中的适用性
  • 设置基于 React 的应用程序的基础结构
  • 设计应用程序的 UI,优化它以便在 React 中使用

什么是反应?

简单地说,React 是一个用于构建可组合用户界面的 JavaScript 库。这意味着我们可以通过组合名为组件的项来构建用户界面。组件是有助于构建用户界面的元素。它可以是一个文本框、一个按钮、一个完整的表单、一组其他组件,等等。甚至整个应用程序的用户界面也是一个组件。因此,React 鼓励创建组件来构建用户界面;如果这些组件是可重用的,那就更好了。

React 组件能够显示随时间变化的数据,并且当我们遵循一些指导原则时,这些变化数据的可视化是自动的。

由于该库涉及用户界面,您可能想知道哪些表示设计模式是受以下启发的:模型视图控制器模型视图演示器模型视图模型或其他东西启发的。React 不受特定呈现模式的约束。React 实现了最常见模式的视图部分,让开发人员自由选择最佳方法来实现模型、演示者以及构建应用程序所需的一切。这方面很重要,因为它允许我们将其分类为库,而不是框架;因此,与 Angular 等框架进行比较可能会发现一些不一致之处。

如何设置基于 React 的应用程序

React 是一个 JavaScript 库,因此我们应该能够通过 HTML 页面中的<script>标记对其进行引用,并开始编写 web 应用程序。但是,这种方法会阻止我们利用现代 JavaScript 开发环境提供的一些功能,这些功能使我们的生活更加轻松。例如,我们将无法使用 ECMAScript 2015+的最新功能,例如类、模块、箭头函数、letconst语句等。或者,我们可以使用这些功能,但只有最新的浏览器才支持它们。

The relationship of ECMAScript with JavaScript

Using the latest ECMAScript features requires a true development environment, allowing us to transpile our code into ECMAScript 5 version JavaScript code, so that even older browsers will be able to run our application. Setting up a modern JavaScript development environment requires the installation and configuration of a few tools: a transpiler, a syntax checker, a module bundler, a task runner, and so on. Learning to use these tools properly requires a lot of time, even before starting to write a single line of code.

安装 CreateReact 应用程序

幸运的是,我们可以使用create-react-app,一个命令行界面CLI工具),它允许我们在不需要配置上述任何工具的情况下设置基于 React 的应用程序。它基于 Node.js,并提供命令来立即设置和修改 React 应用程序。

为了安装create-react-app,您的机器上需要安装 Node.js。可以通过在控制台窗口中键入以下命令来安装 CLI:

npm install -g create-react-app

安装后,您可以通过键入以下命令来验证它是否正确安装:

create-react-app --version

如果一切正常,则显示create-react-app的安装版本。

创建第一个 React 应用程序

现在已经安装了开发环境,让我们创建第一个 React 应用程序。我们可以通过在控制台窗口中键入以下命令来完成此操作:

create-react-app hello-react

此命令告诉create-react-app为名为hello-react的基于 React 的应用程序设置所有先决条件。创建过程可能需要几分钟,因为它必须下载项目所需的 npm 包。

npm is the standard package manager of the Node.js environment. When the process ends, you will find a list of the available commands that you can run to manage the project on the screen. We will return to this later. The result of the project creation will be a folder named hello-react, inside of which you will find the items composing a dummy—but working—React-based application.

活动:使用 create react app 创建应用程序

场景

我们需要建立一个开发环境,以便创建一个使用 React 构建的产品目录应用程序。

瞄准

活动的目的是开始熟悉create-react-app及其创建的内容。

完成步骤

  1. 使用create-react-app创建开发环境
  2. 为示例应用程序提供名称my-shop

溶液

没有正式的解决办法。您应该关注create-react-app创建的内容,因为我们将在下面的章节中对其进行分析。

探索生成的内容

让我们看一下由 OrthT0T 生成的文件,这样我们就可以了解基于反应的应用程序的结构。我们将在HELLO-REACT文件夹中找到这些文件和文件夹,如以下屏幕截图所示:

在根文件夹中,我们可以看到一个README.md文件、package.json文件和.gitignore文件。

README文档包含开始构建基于 React 的应用程序所需的所有参考。它是以降价格式编写的,您可以将其与自己的文档集成或覆盖。

Markdown is a simple markup language, often used to create technical documentation for software libraries. It requires a simple text editor, and it is possible to convert a Markdown document into HTML.

package.json文件包含有关项目的信息,如名称、版本等,以及对当前项目使用的所有 npm 包的引用。这是一个 Node.js 资产,允许您在将项目复制到另一台计算机时下载所需的包。它还包含允许我们管理项目本身的脚本定义。

以下是package.json文件内容示例:

{
  "name": "hello-react",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.0.0",
    "react-dom": "^16.0.0",
    "react-scripts": "1.0.14"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

如我们所见,该文件的内容是一个 JSON 对象,具有一些易于识别的属性。特别是,我们可以识别项目的名称、版本和包依赖项。除了名称和版本属性外,通常不需要手动更改这些设置。

在基于 Unix 的系统中,.gitignore文件是一个隐藏文件,它允许我们跟踪在使用 Git 作为版本控制系统时忽略哪些文件。create-react-app工具添加了此文件,因为现在,在版本控制下进行项目是必不可少的。它建议使用 Git,因为它是最流行的版本控制系统之一。

public文件夹包含我们应用程序的静态部分:

  • favicon:这是浏览器地址栏中显示的图标,用于书签
  • index.html:这是 HTML 页面,包含对 React 代码的引用,并提供 React 呈现的上下文
  • manifest.json:根据渐进式 Web 应用程序PWA标准)包含元数据的配置文件

特别是,index.html文件是我们应用程序的起点。让我们来看看它,以便我们能理解它有什么特别之处:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
...
    <title>React App</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
  <div id="root"></div>
...
</html>

正如我们所看到的,它是一个标准的 HTML 页面;但是,需要注意的是,首先,我们看到一个指向manifest.json文件的链接:

<link rel="manifest" href="%PUBLIC_URL%/manifest.json">

此清单包含用于将我们的应用程序配置为 PWA 的元数据。

Progressive web apps are web applications that work for every browser and every platform, even offline. Their basic tenet is responsiveness and progressive enhancement.

我们注意到的第二件事是两个链接引用中的%PUBLIC_URL%占位符:

<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">

在构建过程中,此占位符将替换为public文件夹的实际 URL。

HTML 页面的主体包含一个带有根标识符的空div。这是正确设置 React 应用程序的一项重要内容,我们将很快看到这一点。除了<noscript>标记,我们在主体中看不到任何其他元素。但是,我们需要 HTML 页面和 JavaScript 之间的绑定。构建过程将负责向主体添加所需的脚本。

We can add any other required items to the HTML page, such as meta tags, web fonts, and so on. However, remember that files referenced inside the HTML markup should be put in the public folder. The node_modules folder contains the npm packages used by the project. Usually, you don't need to directly manage these files.

开发应用程序最重要的文件夹是src文件夹。它包含基本文件,以及我们可以根据需要修改的代码。

特别是,我们将找到以下文件:

  • index.js:包含我们应用程序的起点
  • index.css:存储应用程序的基本样式
  • App.js:包含示例应用程序主要组件的定义
  • App.css:包含App组件的样式
  • logo.svg:这是 React 的标志
  • App.test.js:存储涉及App组件的基本单元测试
  • registerServiceWorker.js:包含根据 PWA 要求注册服务人员以允许离线行为的代码

让我们分析其中两个文件的内容,因为它们的代码对于理解 React 应用程序的启动方式至关重要。

让我们从index.js文件开始。其内容如下:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

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

它是一个 ECMAScript 2015 模块,用于导入其他模块。特别是,它分别从reactreact-dom模块导入ReactReactDOM对象。这两个模块都是 React 库的一部分,存储在node_modules文件夹中。

react模块提供组件创建和状态管理功能。react-dom模块是 React 组件和 HTMLDOM 之间的粘合剂。React 库分为两个模块,以便将组件管理与实际渲染分开。当我们想要针对一个不是 web 的渲染平台时,这种分离可能很有用;例如,如果我们希望以本机移动渲染为目标。

其他模块从与index.js文件相同的文件夹导入。特别是,我们从App模块导入App组件。App组件由ReactDOM对象的render()方法使用,以便将其绑定到 HTML 页面中的div元素。此魔术由以下语句执行:

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

现在,让我们忽略用于呈现App组件的语法。这将在下一章中介绍。此语句的含义是将App模块内定义的 ReactApp组件与rootID 标识的 HTML 元素相关联。

registerServiceWorker()函数导入和调用支持离线行为,符合 PWA 规范,而index.css的导入使 CSS 样式可用于应用程序。

App.js文件包含表示应用程序的 React 组件的定义。其内容如下所示:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
...
export default App;

让我们快速查看代码,因为它将在下一章中详细介绍。目前,我们只想了解一个反应组件是如何定义的非常基本的概念。在这里,我们看到一个模块从其他模块导入了一些项,通过继承Component类定义App类,并将App类本身导出为默认导出。就这些,就目前而言。我们将在下一章中深入介绍此代码,详细理解其含义。

createreact 应用程序命令

create-react-appCLI 提供了一些用于管理 React 项目的命令。这些命令以npm <command>的形式出现,因为它们基于 npm。

If you prefer to use YARN as a package manager, you should replace yarn wherever you find npm.

npmstart 命令

我们将覆盖的第一个命令是npm start。此命令启动开发 web 服务器,在http://localhost:3000接受请求。

因此,启动此命令后,我们可以打开浏览器并看到以下结果:

开发 web 服务器有一个热重新加载系统,允许我们更改应用程序的代码,并在保存文件后在浏览器中刷新页面。

更改文件内容并查看结果

以下步骤显示更改文件内容如何导致应用程序在浏览器中重新加载:

  1. 打开控制台窗口。
  2. 转到hello-react文件夹。
  3. 运行npm start
  4. 启动浏览器并转到http://localhost:3000
  5. 启动文本编辑器并打开App.js文件。
  6. 搜索以下代码行:
To get started, edit <code>src/App.js</code> and save to reload.
  1. 用以下代码行替换步骤 6 中提到的代码:
Hello React!
  1. 保存文件。
  2. 检查浏览器内容。现在它应该显示新文本。

活动:启动和更改应用程序

场景

我们希望更改在上一活动中创建的应用程序的标题。

瞄准

本活动的目的是熟悉启动应用程序并欣赏热重新加载功能。

完成步骤

  1. 启动应用程序,以便在浏览器中看到它
  2. 编辑App.js文件并将标题设置为My Shop

溶液

没有正式的解决方案。您应该专注于正确更改标题和运行应用程序。

npm 测试命令

create-react-app通过生成一个示例单元测试文件(如我们已经看到的)以及提供一组运行此类测试的工具,促进了单元测试的使用。

这些工具基于Jest,我们可以通过运行以下命令来运行应用程序中编写的测试:

npm test

此命令将开始运行测试并显示结果,如以下屏幕截图所示:

npm 运行 build 命令

当我们准备将应用程序移动到生产环境中时,我们需要发布工件。我们可以通过运行以下命令来生成这些工件:

npm run build

运行此命令的结果是一个新的BUILD文件夹,我们将在其中找到需要移动到生产环境中的所有文件。该命令对开发环境的文件执行一些处理。简单地说,它将我们编写的所有 ES2015 代码转换为与 ES5 兼容的代码,因此它也适用于较旧的浏览器。这个过程称为发丝。此外,它减少了代码本身的大小,允许通过网络更快地下载。这个过程称为缩小。最后,它在我们的开发环境中获取这些文件,并将它们组合成几个文件,称为 bundle,以减少网络请求。

下面的屏幕截图显示了示例应用程序的BUILD文件夹的内容:

要发布应用程序的生产版本,我们只需将BUILD文件夹的内容复制到生产服务器的文件夹中即可。

The result of the production build assumes that the artifact will be published into the web server root, that is, at a location where the application will be accessible through a URL such as http://www.myapplication.com.

If we need to publish the application in a root's subfolder, that is, at a location where the application will be accessible through a URL such as http://www.myapplication.com/app, we need to make a slight change to the package.json file.

In this case, we need to add a homepage key to the configuration JSON with the URL as its value, as shown here: "homepage": "http://www.myapplication.com/app".

npm 运行弹出命令

我们将讨论的最后一个命令是eject命令:

npm run eject

当我们有信心使用create-react-app基础工具并且需要自定义环境配置时,我们可以使用此命令。此命令使我们的应用程序脱离 CLI 上下文,并赋予我们管理它的权力和责任。

This is a one-way process. If we leave the create-react-app context for our application, we cannot go back.

如何设计用户界面

现在,我们将看看如何设计我们的应用程序,使其在使用 React 实现时非常适合。

一切都是一个组成部分

React 在用户界面设计和实现中引入的主要概念是组件概念。用户界面是组件的集合,而整个 React 应用程序是组件的集合。现在,我们将从设计角度更详细地了解哪些组件。

From a design point of view, we can say that a component is a part of the user interface, having a specific role. A hierarchy of components is often called a component tree.

考虑网页中的表单。它可以被视为一个组件,因为它有一个特定的角色:收集数据并将其发送到服务器。此外,表单中的文本框可以被视为一个组件。它有一个特定的角色:收集将发送到服务器的单个数据段。因此,一个组件可能包含其他组件。这就是通常发生的情况:用户界面是组件的层次结构,其中一些组件包含其他组件。

记住这个概念,因为它对于实现高效和可重用的用户界面是有用的。

分解用户界面

为了更好地理解如何设计用户界面以及如何创建组件来实现它们,我们将尝试将著名的 web 用户界面分解为 YouTube 主页:

我们可以在这个页面上检测到几个项目,每个项目都有一个特定的角色,从页面本身开始,其角色是允许用户与系统交互。

如果我们考虑页眉、左边栏和主区域,所有这些项都是页面的组成部分。您可以在以下屏幕截图中看到它们高亮显示:

当然,我们可以继续检测其他组件。例如,我们可以将主要区域中的每个视频预览框视为组件。您可以在以下屏幕截图中看到它们:

此分解过程允许我们关注接口中每个项的特定角色,以便我们可以尝试隔离每个功能并创建可重用组件,即仅具有真正重要的依赖关系的组件。

容器和表示组件

我们可以将用户界面中的组件分为容器组件和表示组件。

容器组件是没有相关视觉效果的组件。它们的主要作用是对其他组件进行分组,即,包含其他组件。例如,表单通常是容器组件,因为它的主要作用是包含其他组件,如文本框、标签、按钮等。

表示组件是以某种图形形式显示数据的组件。文本框、日期选择器和工具栏都是表示组件的示例。

为了在 React 中创建高效的用户界面,容器组件和表示组件之间的区别非常重要。稍后,当我们学习管理组件的状态并通过组件传播数据时,我们将利用这一区别。

活动:检测 Web 用户界面中的组件

场景

我们需要转换维基百科网站的用户界面(https://en.wikipedia.org 转化为反应组分。

瞄准

活动的目的是在实现基于 React 的用户界面时解决设计过程。

完成步骤

  1. 分析页面的当前结构,并检测可以作为组件实现的项
  2. 指出哪些是容器,哪些是表示组件

溶液

假设以下是当前 Wikipedia 主页:

可能的解决办法如下。

我们可以检测以下组件:

  • 主页组件包含左侧边栏组件、标题组件和主区域组件。所有这些组件都是容器组件。
  • 左侧组件包含徽标组件(表示)和组件列表(表示)。
  • 标题组件包含一个链接组件(表示)到一般功能的列表。
  • 主区域组件包含选项卡组件(容器)列表和搜索组件(表示)。
  • 选项卡组件包含横幅组件(呈现)、主题索引组件(呈现)和区块组件列表(呈现)。

总结

在本章中,我们开始探索 React 世界。特别是,我们:

  • React 是一个用户界面库,用于实现各种 MV*设计模式的视图部分
  • 介绍了create-react-app工具,它帮助我们建立一个开发环境来构建基于 React 的应用程序
  • 探索了组成一个典型的基于 React 的应用程序的项目
  • 分析了设计最适合 React 世界的用户界面的方法

在下一章中,我们将发现如何创建 React 组件来为我们的应用程序构建用户界面。