跳到主要内容

基础概念

React 简介

什么是React?

React 是一个用于构建用户界面的 JavaScript 库,最初由 Facebook 开发和维护。它主要用于开发单页面应用程序 (SPA),通过构建可复用的组件来创建动态和响应迅速的用户界面。React 的核心理念是声明式编程和组件化,这使得开发和维护复杂的应用程序变得更加容易。

React的特点

组件化:React 采用组件化开发的方式,将用户界面分解成一个个独立的组件,这些组件可以重复使用和组合,提升了代码的可维护性和可复用性。

声明式:React 使用声明式编程来描述用户界面状态,这使得代码更加直观和易于理解。开发者只需要描述应用在某个状态下应该是什么样子,而不需要手动操作 DOM 来更新界面。

虚拟 DOM:React 通过使用虚拟 DOM 来提升性能。虚拟 DOM 是 React 在内存中构建的一棵轻量级 DOM 树,当状态发生变化时,React 通过比较虚拟 DOM 和真实 DOM 的差异(diffing),仅更新需要改变的部分,从而提高了性能。

单向数据流:React 中的数据流是单向的,即数据只能从父组件传递到子组件,这使得数据管理变得更加简单和可预测。

高效:由于虚拟 DOM 和高效的 diff 算法,React 可以在保持性能的同时频繁更新 UI。

JSX

JSX(JavaScript XML)是 React 提供的一种语法扩展,允许在 JavaScript 代码中直接编写 HTML 结构。JSX 使得代码更加直观和简洁,同时提高了代码的可读性。

const element = <h1>Hello, world!</h1>;

JSX 实际上是被 Babel 转译成普通的 JavaScript 代码,例如上面的代码会被转译成:

const element = React.createElement('h1', null, 'Hello, world!');

虚拟DOM

虚拟 DOM 是 React 的一大亮点,它是 React 在内存中维护的一棵轻量级 DOM 树。当组件的状态发生变化时,React 会先在虚拟 DOM 中更新视图,然后再计算出最小的变更部分,最后只更新真实 DOM 中需要变化的部分。这样可以避免不必要的 DOM 操作,从而提升性能。

虚拟 DOM 的工作流程如下:

  1. 当组件状态或属性改变时,React 重新渲染虚拟 DOM。
  2. React 比较新旧虚拟 DOM 的差异,计算出需要更新的部分。
  3. React 将变化的部分更新到真实 DOM 上。

安装和环境配置

创建React项目

Create React App 是官方提供的一个工具,用于快速创建和配置 React 应用程序。它可以帮助开发者避免繁琐的配置步骤,专注于编写代码。

安装 Node.js 和 npm:在创建 React 项目之前,需要确保已经安装了 Node.js 和 npm(Node 包管理器)。可以从 Node.js 官网 下载并安装最新版本。

创建项目
# 安装最新版本
npx create-react-app@latest project_name

# 进入项目
cd project_name

# 运行
npm start

项目结构介绍

Create React App 创建的项目典型结构如下:

my-app/
├── node_modules/ # 包含项目的所有依赖包
├── public/ # 静态资源
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src/ # 项目文件
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css # 全局样式文件
│ ├── index.js # React 入口文件
│ ├── logo.svg
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore # git忽略文件
├── package.json # node工具包管理文件
├── package-lock.json
└── README.md # 项目的自述文件

常用开发工具和插件

代码编辑器:IDEA

浏览器开发插件:React Developer Tools

版本控制工具:git

JavaScriptXML

什么是 JSX?

JSX (JavaScript XML) 是一种语法扩展,允许在 JavaScript 代码中编写类似 HTML 的结构。它被 React 用来描述用户界面。尽管看起来像 HTML,JSX 实际上会被 Babel 转译成 JavaScript 函数调用,从而生成 React 元素。这使得定义组件的 UI 结构更加直观和简洁。

JSX 语法

JSX 语法允许在 JavaScript 中嵌入 XML/HTML 代码。以下是一些常见的 JSX 语法示例:

示例
const element = <h1>Hello, world!</h1>;

// 嵌套元素
const element2 = (
<div>
<h1>Hello, world!</h1>
<p>Welcome to learning React!</p>
</div>
);

在 React JSX 语法中绑定属性、类名和事件和HTML略有不同,属性和事件均采用小驼峰命名法:

属性
const element = <input type="text" defaultValue="Hello" />;
事件
const handleClick = () => {
console.log('Button clicked!');
};

const element = <button onClick={handleClick}>Click Me</button>;

由于 class 是 JavaScript 的保留字,React 使用 className 来指定 CSS 类名:

类名
const element = <div className="my-class"></div>;

表达式与 JSX

在 JSX 中可以使用大括号 {} 来嵌入 JavaScript 表达式,这些表达式会被求值并插入到最终的输出中。

变量
const name = 'John';
const element = <h1>Hello, {name}!</h1>;
函数调用
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}

const user = {
firstName: 'Harper',
lastName: 'Perez',
};

const element = <h1>Hello, {formatName(user)}!</h1>;
三元运算符
const isLoggedIn = true;
const element = <div>{isLoggedIn ? 'Welcome back!' : 'Please sign up.'}</div>;
嵌套表达式
const element = (
<div>
<h1>{name ? `Hello, ${name}!` : 'Hello, Stranger!'}</h1>
</div>
);

只能返回一个根元素

如果想要在一个组件中包含多个元素,需要用一个父标签把它们包裹起来。

const element = (
<div>
<h1>海蒂·拉玛的待办事项</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
/>
</div>
);

如果你不想在标签中增加一个额外的 <div>,可以用 <></> 元素来代替:

这个空标签被称作 Fragment。React Fragment 允许你将子元素分组,而不会在 HTML 结构中添加额外节点。

为什么多个 JSX 标签需要被一个父元素包裹?

JSX 虽然看起来很像 HTML,但在底层其实被转化为了 JavaScript 对象,你不能在一个函数中返回多个对象,除非用一个数组把他们包装起来。这就是为什么多个 JSX 标签必须要用一个父元素或者 Fragment 来包裹。

标签必须闭合

JSX 要求标签必须正确闭合。像 <img> 这样的自闭合标签必须书写成 <img />,而像 <li>oranges 这样只有开始标签的元素必须带有闭合标签,需要改为 <li>oranges</li>

使用驼峰式命名法给大部分属性命名

JSX 最终会被转化为 JavaScript,而 JSX 中的属性也会变成 JavaScript 对象中的键值对。在你自己的组件中,经常会遇到需要用变量的方式读取这些属性的时候。但 JavaScript 对变量的命名有限制。例如,变量名称不能包含 - 符号或者像 class 这样的保留字。

这就是为什么在 React 中,大部分 HTML 和 SVG 属性都用驼峰式命名法表示。例如,需要用 strokeWidth 代替 stroke-width。由于 class 是一个保留字,所以在 React 中需要用 className 来代替。

使用 “双大括号”:JSX 中的 CSS 和 对象

除了字符串、数字和其它 JavaScript 表达式,你甚至可以在 JSX 中传递对象。对象也用大括号表示,例如 { name: "Hedy Lamarr", inventions: 5 }。因此,为了能在 JSX 中传递,你必须用另一对额外的大括号包裹对象:person={{ name: "Hedy Lamarr", inventions: 5 }}

你可能在 JSX 的内联 CSS 样式中就已经见过这种写法了。React 不要求你使用内联样式(使用 CSS 类就能满足大部分情况)。但是当你需要内联样式的时候,你可以给 style 属性传递一个对象:

export default function TodoList() {
return (
<ul
style={{
backgroundColor: 'black',
color: 'pink',
}}
>
<li>打篮球</li>
<li>看书</li>
<li>写代码</li>
</ul>
);
}
拆解Style
export default function TodoList() {
let style = {
backgroundColor: 'black',
color: 'pink',
};

return (
<ul style={style}>
<li>打篮球</li>
<li>看书</li>
<li>写代码</li>
</ul>
);
}

所以当你下次在 JSX 中看到 {{}} 时,就知道它只不过是包在大括号里的一个对象罢了!

JSX 与 HTML 的区别

尽管 JSX 看起来非常像 HTML,但它们之间有一些重要的区别:

属性命名:

在 JSX 中,属性名称采用驼峰命名法,如 classNameonClick,而在 HTML 中是用小写,如 classonclick

jsx
const element = <div className="container"></div>;
html
<div class="container"></div>

自闭合标签:

在 JSX 中,所有自闭合标签必须显式关闭,如 <img /><input />,而在 HTML 中则可以省略斜杠。

jsx
const element = <img src="image.png" />;
html
<img src="image.png" />

JavaScript 表达式:

在 JSX 中,可以使用 {} 来嵌入 JavaScript 表达式,而在 HTML 中只能使用静态值。

jsx
const name = 'John';

const element = <h1>Hello, {name}!</h1>;
html
<h1>Hello, John!</h1>

注释:

在 JSX 中,注释使用 {/* */},而在 HTML 中使用 <!-- -->

jsx
const element = <div>{/* 注释内容 */}</div>;
html
<!-- 注释内容 -->
JSX 注释

在 JSX 中,花括号 {} 用来嵌入 JavaScript 表达式,因此可以利用花括号内的注释形式 /* */ 来实现 JSX 注释。