跳到主要内容

基础概念

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 中,属性名称采用驼峰命名法,如 className、onClick,而在 HTML 中是用小写,如 class、onclick。

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 注释。