React官网学习记录
1. 首页
React:用于构建 Web 和原生用户界面的库。
用组件创建用户界面:React 让你可以通过组件来构建用户界面。
用代码和标签编写组件:React 组件是 JavaScript 函数。想要有条件地显示一些内容吗?使用 if
语句。 想要展示一个列表?尝试使用数组的 map()
方法。学习 React 就是学习编程。这种标签语法被称为 JSX,它是由 React 推广的 JavaScript 语法扩展。将 JSX 标签与相关的渲染逻辑放在一起,使得创建、维护和删除 React 组件变得容易。
在任何地方添加交互:React 组件接收数据并返回应该出现在屏幕上的内容。你可以通过响应交互(例如用户输入)向它们传递新数据。然后,React 将更新屏幕以匹配新数据。
2. 学习 React
2.1 快速入门
欢迎来到 React 文档!本章节将介绍你每天都会使用的 80% 的 React 概念。
创建和嵌套组件
React 应用程序是由 组件 组成的。一个组件是 UI(用户界面)的一部分,它拥有自己的逻辑和外观。组件可以小到一个按钮,也可以大到整个页面。
React 组件必须以大写字母开头,而 HTML 标签则必须是小写字母。
React 组件是返回标签的 JavaScript 函数:
// 创建
function MyButton() {
return (
<button>I'm a button</button>
);
}
// 使用
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}
使用 JSX 编写标签
上面所使用的标签语法被称为 JSX。它是可选的,但大多数 React 项目会使用 JSX,主要是它很方便。
JSX 比 HTML 更加严格。你必须闭合标签,如 <br />
。你的组件也不能返回多个 JSX 标签。你必须将它们包裹到一个共享的父级中,比如 <div>...</div>
或使用空的 Fragment( <>...</>
)包裹。
添加样式
在 React 中,你可以使用 className
来指定一个 CSS 的 class。它与 HTML 的 class
属性的工作方式相同;然后,你可以在一个单独的 CSS 文件中为它编写 CSS 规则:
<img className="avatar" />
.avatar {
border-radius: 50%;
}
显示数据
JSX 会让你把标签放到 JavaScript 中。而大括号会让你 “转义回” JavaScript 中,这样你就可以从你的代码中嵌入一些变量并展示给用户。例如,这将显示 user.name
:
return (
<h1>
{user.name}
</h1>
);
// style={{}} 并不是一个特殊的语法,而是 style={ },JSX 大括号内的一个普通 {} 对象
<img
className="avatar"
src={user.imageUrl}
alt={'Photo of ' + user.name}
style={{
width: user.imageSize,
height: user.imageSize
}}
/>
条件渲染
React 没有特殊的语法来编写条件语句,因此你使用的就是普通的 JavaScript 代码。
let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);
<div>
{ isLoggedIn ? (<AdminPanel />) : (<LoginForm />) }
</div>
<div>
{ isLoggedIn && <AdminPanel /> }
</div>
渲染列表
你将依赖 JavaScript 的特性,例如 for
循环 和 array 的 map()
函数 来渲染组件列表。
const products = [];
const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
响应事件
可以通过在组件中声明 事件处理 函数来响应事件:
function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
注意,onClick={handleClick}
的结尾没有小括号!不要 调用 事件处理函数:你只需 把函数传递给事件 即可。当用户点击按钮时 React 会调用你传递的事件处理函数。
更新界面
通常你会希望你的组件 “记住” 一些信息并展示出来,比如一个按钮被点击的次数。
import { useState } from 'react';
function MyButton() {
const [count, setCount] = useState(0);
// ...
}
你将从 useState
中获得两样东西:当前的 state(count
),以及用于更新它的函数(setCount
)。你可以给它们起任何名字,但按照惯例会像 [something, setSomething]
这样为它们命名。
React 将再次调用你的组件函数。
使用 Hook
以 use
开头的函数被称为 Hook。useState
是 React 提供的一个内置 Hook。你可以在 React API 参考 中找到其他内置的 Hook。你也可以通过组合现有的 Hook 来编写属于你自己的 Hook。
Hook 比普通函数更为严格。你只能在你的组件(或其他 Hook)的 顶层 调用 Hook。如果你想在一个条件或循环中使用 useState
,请提取一个新的组件并在组件内部使用它。
组件间共享数据
可能经常需要组件 共享数据并一起更新。可以通过 “状态提升”,向上移动 state,实现在组件间共享它。
2.2 安装
React 从诞生之初就是可被渐进式使用的。因此你可以选择性地使用 React 特性。不管你是想体验下 React,用它为简单的 HTML 页面增加交互,还是重新搭建一个由 React 驱动的复杂应用,本章节内容都能帮你快速入门。
开始新的 React 项目
如果你想完全使用 React 构建一个新的应用或一个新的网站,我们建议你选择社区中流行的 React 支持的框架之一。你可以在没有框架的情况下使用 React,但是我们发现大多数应用和网站最终都会构建常见问题的解决方案,例如代码分割、路由、数据获取和生成 HTML。这些问题对于所有 UI 库都很常见,而不仅仅是 React。
从框架开始一个项目,你就可以快速使用 React,这样以后也不需要构建自己的框架。
生产级 React 框架:这些框架支持在生产中部署和扩展应用程序所需的所有功能,并正在努力支持我们的 全栈架构愿景。
- Next.js
- Remix
- Gatsby
- Expo(用于原生应用)
前沿的 React 框架:在我们探索如何继续改进 React 的过程中,我们意识到将 React 与框架(特别是路由、打包和服务端技术)更紧密地结合起来是我们帮助 React 用户构建更好的应用的最大机会。Next.js 团队已经同意与我们合作研究、开发、集成和测试与框架无关的 React 前沿功能,如 React 服务器组件。
将 React 添加到现有项目
如果想对现有项目添加一些交互,不必使用 React 将其整个重写。只需将 React 添加到已有技术栈中,就可以在任何位置渲染交互式的 React 组件。官网链接。
在现有网站的子路由中使用 React:1、使用基于 React 的框架构建应用的 React 部分;2、在框架配置中指定 /some-app
作为基本路径;3、配置服务器或代理,以便所有位于 /some-app/
下的请求都由 React 应用处理。
在现有页面的一部分中使用 React:1、配置 JavaScript 环境,以便使用 JSX 语法、import
和 export
语法将代码拆分为模块,以及从 npm 包注册表中使用包(例如 React);2、在需要的位置渲染 React 组件。
编辑器设置
正确配置的编辑器可以使代码更易读和更快地编写。它甚至可以帮助你在编写错误时发现错误!
推荐的文本编辑器功能:
- 代码检查(Linting):代码检查可以在你编写代码时,发现代码中的问题,以帮你尽早修复。ESLint 是一款流行且开源的 JavaScript 代码检查工具。
- 格式化(Formatting):与其他贡献者共享你的代码时,你最不想做的就是参与有关 制表符与空格 的讨论!幸运的是,Prettier 会根据预设配置的规则重新格式化代码,以保证代码整洁。运行 Prettier,你的所有制表符都将转换为空格,并且你的缩进、引号等也将全部更改以符合配置。
使用 TypeScript
TypeScript 是一种向 JavaScript 代码库添加类型定义的流行方法。开箱即用的 TypeScript 支持 JSX,只需在项目中添加 @types/react
和 @types/react-dom
即可获得完整的 React Web 支持。
React 开发者工具
使用 React 开发者工具检查 React components
,编辑 props
和 state
,并识别性能问题。
浏览器扩展:调试 React 构建的网站最简单的办法就是安装 React 开发者工具浏览器扩展。安装 Chrome 扩展。
3. 学习 React -- 描述 UI
React 是一个用于构建用户界面(UI)的 JavaScript 库,用户界面由按钮、文本和图像等小单元内容构建而成。React 允许你将它们组合成可重用、可嵌套的组件。从 Web 端网站到移动端应用,屏幕上的所有内容都可以分解成组件。
3.1 你的第一个组件
React 应用是由被称为 组件 的独立 UI 片段构建而成。React 组件本质上是可以任意添加标签的 JavaScript 函数。组件可以小到一个按钮,也可以大到是整个页面。
概览
组件是 React 的核心概念之一。它们是构建用户界面(UI)的基础,是 UI 构成要素。
React 允许你将标签、CSS 和 JavaScript 组合成自定义“组件”,即 应用程序中可复用的 UI 元素。
定义组件
React 组件是一段可以 使用标签进行扩展 的 JavaScript 函数。
WARNING
React 组件是常规的 JavaScript 函数,但 组件的名称必须以大写字母开头,否则它们将无法运行!
// 返回语句可以全写在一行上
return <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />;
// 但是,如果你的标签和 return 关键字不在同一行,则必须把它包裹在一对括号中
return (
<div>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</div>
);
WARNING
没有括号包裹的话,任何在 return
下一行的代码都 将被忽略!
使用组件
WARNING
组件可以渲染其他组件,但是 请不要嵌套他们的定义:
export default function Gallery() {
// 🔴 永远不要在组件中定义组件
function Profile() {
// ...
}
// ...
}
上面这段代码 非常慢,并且会导致 bug 产生。因此,你应该在顶层定义每个组件:
export default function Gallery() {
// ...
}
// ✅ 在顶层声明组件
function Profile() {
// ...
}
当子组件需要使用父组件的数据时,你需要 通过 props 的形式进行传递,而不是嵌套定义。
深入探讨
万物皆组件。
3.2 组件的导入与导出
你可以在一个文件中声明许多组件,但文件的体积过大会变得难以浏览。为了解决这个问题,你可以在一个文件中只导出一个组件,然后再从另一个文件中导入该组件。
概览
组件的神奇之处在于它们的可重用性:你可以创建一个由其他组件构成的组件。但当你嵌套了越来越多的组件时,则需要将它们拆分成不同的文件。这样可以使得查找文件更加容易,并且能在更多地方复用这些组件。
导出与导入
为了使组件模块化,并且可在其他文件中复用。你可以根据以下三个步骤对组件进行拆分:
- 创建 一个新的 JS 文件来存放该组件。
- 导出 该文件中的函数组件(可以使用 默认导出 或 具名导出)
- 在需要使用该组件的文件中 导入(可以根据相应的导出方式使用 默认导入 或 具名导入)。
- 同一文件中,有且仅有一个默认导出,但可以有多个具名导出!
语法 | 导出语句 | 导入语句 |
---|---|---|
默认 | export default function Button() {} | import Button from './Button.js'; |
具名 | export function Button() {} | import { Button } from './Button.js'; |
TIP
引入过程中,你可能会遇到一些文件并未添加 .js
文件后缀,如下所示:
import Gallery from './Gallery';
无论是 './Gallery.js'
还是 './Gallery'
,在 React 里都能正常使用,只是前者更符合 原生 ES 模块。
3.3 使用 JSX 编写标签
每个 React 组件都是一个 JavaScript 函数,它可能包含一些标签,React 会将其渲染到浏览器中。React 组件使用一种叫做 JSX 的语法扩展来表示该标签。JSX 看起来很像 HTML,但它更为严格,可以显示动态信息。
将标签引入 JavaScript
网页是构建在 HTML、CSS 和 JavaScript 之上的。多年以来,Web 开发者都是将网页内容存放在 HTML 中,样式放在 CSS 中,而逻辑则放在 JavaScript 中 —— 通常是在不同的文件中!但随着 Web 的交互性越来越强,逻辑越来越决定页面中的内容。JavaScript 控制着 HTML 的内容!这也是为什么 在 React 中,渲染逻辑和标签共同存在于同一个地方——组件。
WARNING
JSX and React 是相互独立的 东西。但它们经常一起使用,但你 可以 单独使用它们中的任意一个,JSX 是一种语法扩展,而 React 则是一个 JavaScript 的库。
JSX 规则
- 只能返回一个根元素。
- 标签必须闭合。
- 使用驼峰式命名法给
所有大部分属性命名!JSX 最终会被转化为 JavaScript,而 JSX 中的属性也会变成 JavaScript 对象中的键值对。在你自己的组件中,经常会遇到需要用变量的方式读取这些属性的时候。但 JavaScript 对变量的命名有限制。例如,变量名称不能包含-
符号或者像class
这样的保留字(所以在 React 中需要用className
来代替)。
深入探讨
为什么多个 JSX 标签需要被一个父元素包裹?
JSX 虽然看起来很像 HTML,但在底层其实被转化为了 JavaScript 对象,你不能在一个函数中返回多个对象,除非用一个数组把他们包装起来。这就是为什么多个 JSX 标签必须要用一个父元素或者 Fragment 来包裹。
3.4 在 JSX 中通过大括号使用 JavaScript
JSX 可以让你在 JavaScript 文件中编写类似 HTML 的标签语法,使渲染逻辑和内容展示维护在同一个地方。有时你会想在标签中添加一点 JavaScript 逻辑或引用一个动态属性。在这种情况下,你可以在 JSX 中使用花括号来为 JavaScript “开辟通道”。
大括号可以使你直接在标签中使用 JavaScript!
JSX 是一种编写 JavaScript 的特殊方式。
JSX 是一种模板语言的最小实现,因为它允许你通过 JavaScript 来组织数据和逻辑。
使用引号传递字符串
当你想把一个字符串属性传递给 JSX 时,把它放到单引号或双引号中:
export default function Avatar() {
return (
<img
className="avatar"
src="https://i.imgur.com/7vQD0fPs.jpg"
alt="Gregorio Y. Zara"
/>
);
}
但是如果你想要动态地指定 src
或 alt
的值呢?你可以 用 {
和 }
替代 "
和 "
以使用 JavaScript 变量:
export default function Avatar() {
const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
const description = 'Gregorio Y. Zara';
return (
<img
className="avatar"
src={avatar}
alt={description}
/>
);
}
使用大括号:一扇进入 JavaScript 世界的窗户
- 在 JSX 的大括号内引用 JavaScript 变量
- 在 JSX 的大括号内调用 JavaScript 函数
- 在 JSX 的大括号内使用 JavaScript 对象
export default function TodoList() {
const name = 'Gregorio Y. Zara';
const today = () => new Date();
return (
<h1>{name}'s To Do List</h1>
<h1 style={{
backgroundColor: 'black',
color: 'pink'
}}>
To Do List for {today()}
</h1>
);
}
WARNING
内联 style
属性 使用驼峰命名法编写。例如,HTML <ul style="background-color: black">
在你的组件里应该写成 <ul style={ { backgroundColor: 'black' } }>
。
TIP
{ {
和 } }
并不是什么特殊的语法:它只是包在 JSX 大括号内的 JavaScript 对象。
3.5 将 Props 传递给组件
React 组件使用 props 来进行组件之间的通讯。每个父组件都可以通过为子组件提供 props 的方式来传递信息。props 可能会让你想起 HTML 属性,但你可以通过它们传递任何 JavaScript 值,包括对象、数组、函数、甚至是 JSX (children) !
3.6 条件渲染
你的组件经常需要根据不同的条件来显示不同的东西。在 React 中,你可以使用 JavaScript 语法,如 if
语句、&&
和 ? :
操作符有条件地渲染 JSX。
3.7 渲染列表
通常,你需要根据数据集合来渲染多个较为类似的组件。你可以在 React 中使用 JavaScript 的 filter()
和 map()
来实现数组的过滤和转换,将数据数组转换为组件数组。
对于数组的每个元素项,你需要指定一个 key
。通常你需要使用数据库中的 ID 作为 key
。即使列表发生了变化,React 也可以通过 key 来跟踪每个元素在列表中的位置。
3.8 保持组件纯粹
有些 JavaScript 函数是 纯粹 的。纯函数的基本定义:
- 只负责自己的任务。 它不会更改在该函数调用前就已存在的对象或变量。
- 输入相同,输出也相同。 在输入相同的情况下,对纯函数来说应总是返回相同的结果。
严格遵循纯函数的定义编写组件,可以让代码库体量增长时,避免一些令人困惑的错误和不可预测的行为。
3.9 将 UI 视为树
React 使用树形关系建模以展示组件和模块之间的关系。
React 渲染树是组件之间父子关系的表示。
对 JavaScript 模块之间的关系进行建模是了解应用程序的另一种有用方式。我们将其称为模块依赖树。构建工具经常使用依赖树来捆绑客户端下载和渲染所需的所有 JavaScript 代码。对于 React 应用程序,打包大小会导致用户体验退化。了解模块依赖树有助于调试此类问题。