React

React（也称为React.js或ReactJS）是一个自由及开放源代码的前端JavaScript工具库，用于基于UI组件构建用户界面。

它由Meta（前身为Facebook）和由个人开发者和公司组成的社群维护。

React可用作开发具有Next.js等框架的单页、手机或服务器渲染应用程序的基础。然而，React只专注状态管理和将状态渲染到DOM，因此创建React应用程序通常需要使用额外的工具库来进行路由实作，以及某些客户端功能。

## 基本使用方法

以下是使用JSX和JavaScript在HTML中使用React的基本范例。

```javascript
import React from "react";

const Greeting = () => {
  return (
    <div className="hello_world">
      <h1> Hello, world! </h1>
    </div>
  );
};

export default Greeting;
```

Greeting函数是一个React组件，渲染的结果为“Hello, world”。

在网页浏览器中显示时，结果将是以下内容的渲染：

```html
<div class="hello_world">
  <h1>Hello, world!</h1>
</div>
```

## 功能

### 宣告式语法

React采取宣告式程式撰写范式。开发人员为应用程序的每个状态设计视图，React会在资料更改时更新和呈现组件。这与命令式程式撰写不同。

### 组件

React程式码由称为组件的实体组成。这些组件是可重复利用的，并且必须遵循大写驼峰命名法（Pascal Case）作为其命名规则，也就是大写版本的驼峰式命名法（camelCase）在src资料夹中形成。可以使用React DOM工具库将组件渲染到DOM中的特定元素。渲染组件时，可以通过“props”在组件之间传递参数值：

```javascript
import React from "react";
import Tool from "./Tool";
const Example = () => {
  return (
    <>
      <div className="app">
        <Tool name="Gulshan" />
      </div>
    </>
  );
};
  
export default Example;
```

在上面的范例中，值为“Gulshan”的name属性已从`Example`组件传递到`Tool`组件。

此外，`return`部分被包装在一个名为`return`的标签中，因为只能返回一个值。所以所有JSX元素和组件都绑定到一个标签中。

在React中宣告组件的两种主要方式是通过函数组件和基于类别组件。

### 函数组件

函数组件用一个函数声明，然后返回一些JSX。

```js
const Greeter = () => <div>Hello World</div>;
```

### 类别组件

基于类的组件使用ES6类别宣告。

```js
class ParentComponent extends React.Component {
  state = { color: 'green' };
  render() {
    return (
      <ChildComponent color={this.state.color} />
    );
  }
}
```

类别组件都是关于类别的使用和生命周期方法的，而功能组件有Hooks来处理在React中编写代码时出现的状态管理和其他问题。

### 虚拟DOM

另一个值得注意的特性是使用虚拟文件物件模型（DOM）。React建立一个内存资料结构暂存，计算结果差异，然后有效地更新浏览器显示的DOM。这个过程称为reconciliation。这允许程式工程师撰写程式码，就好像每次更改都会渲染整个页面，而React只渲染实际更改的子组件。这种选择性渲染带来了主要的性能提升。节省了重新计算CSS样式、页面排版和渲染整个页面的工作量。

### 生命周期方法

基于类别组件的生命周期方法使用一种挂钩（Hooking）形式，允许在组件生命周期内的设定点执行程式码。

- `shouldComponentUpdate` 允许开发人员通过在不需要渲染时返回false来防止不必要的组件重新渲染。
- `componentDidMount`只要一旦组件“挂载（mounted）”（组件已在用户界面中建立，通常通过将其与DOM节点关联），就会被呼叫。这通常用于通过API触发从远端资料来源载入资料。
- `componentWillUnmount` 在组件被移除或“卸载”（unmounted）之前立即被呼叫。通常用于清除对组件的资源需求相依性模组，这相依性模组不会随着组件的卸载而容易地被删除（例如，删除与组件相关的任何 `setInterval()`，或设定于“文件”的“事件监听”（`eventListener`），因为组件的存在）。
- `render`是最重要的生命周期方法，也是任何组件中唯一需要的方法。它通常在每次组件状态更新时呼叫，也就是应该反映在用户界面中。

### JSX

JSX或JavaScript语法扩充，是JavaScript语言语法的扩充。在外表上与HTML类似，JSX提供了一种使用许多开发人员熟悉的语法来构建组件渲染的方法。React组件通常使用JSX撰写，尽管它们并非必须如此（组件也可以使用纯JavaScript撰写）。JSX类似于Facebook为PHP创建的另一个扩展语法，称为XHP。

JSX代码范例：

```javascript
class App extends React.Component {
  render() {
    return (
      <div>
        <p>Header</p>
        <p>Content</p>
        <p>Footer</p>
      </div>
    );
  }
}
```

#### 嵌套的元素

同一层级上的多个元素需要包装在一个React元素中。例如上面代码中，`<p>` 被包裹在 `<div>` 元素中。否则需要由 `<Fragment>` 或其简写形式 `<>` 包围，或作为数组返回。

### HTML之外的架构

React的基本架构不仅适用于在浏览器中呈现HTML。例如，Facebook有渲染到`<canvas>`标签， Netflix 和 PayPal 使用通用载入于服务器和客户端上渲染相同的HTML。

### React hooks

Hooks是让开发人员从函数组件中“钩入（Hook into）”React状态和生命周期特性的函数。Hooks在类别组件无法作用——它们让你在没用类别组件情况下使用React。

React提供了一些内建的Hook，例如 `useState`,`useContext`、`useReducer`、`useMemo` 与`useEffect`。其他的记录在Hooks API参考中。`useState` 与`useEffect`，也就是最常用，分别用于状态和副作用的控制。

#### Hooks的使用规范

下面有一些Hooks规范 描述了钩子（Hooks）的特征程式码模式，也是现今使用React处理状态方式。

- Hooks只能在顶层呼叫（而不是在循环或if语句内）。
- Hooks只能从React函数组件和自定义Hooks呼叫，而不是普通函数或类别组件。

虽然这些规范不能在执行时强制执行，但可以设定程式码分析工具（例如linter）来侦测开发过程中的许多错误。

这些规范适用于Hooks的使用和自定义Hooks的实作，也就是可能会调用其他Hooks。

## 常用惯用语

React并不刻意提供一个完整的“应用程序工具库”。专为构建用户界面而设计，因此不包含一些开发人员可能认为构建应用程序所必需的许多工具。这也允许选择开发人员喜欢的任何工具库来完成诸如执行网络访问或本地资料存储等任务。随着工具库的成熟，常见的使用模式已经出现。

### 单向资料流

为了支援React的单向资料流概念（可能与 AngularJS 的双向资料流形成对比），Flux架构被开发为流行的模型-视图-控制器架构的替代方案。Flux具有通过中央调度程式发送到储存区（Store）的操作，并且对储存区的更改被传递回视图。当与React一起使用时，这种传递是通过组件属性完成的。从Flux的概念开始，Flux就被Redux和MobX等工具库所取代。

Flux可以被认为是观察者模式的一种变体。

Flux架构下的React组件不应直接修改传递给它的任何props，而应传递回调函数，这些回呼函数创建由调度程式发送的用于修改存储的操作。动作（Action）是一个对象，负责描述发生的事情：例如，描述一个用户“关注”另一个用户的动作可能包含用户ID、目标用户ID和类型`USER_FOLLOWED_ANOTHER_USER`。可以将存储视为模型，可以根据从调度程式接收到的操作来改变自己。

这种模式有时表示为“属性（Properties）向下流动，动作（Actions）向上流动”。Flux的许多实作从一开始就被建立了，也许最著名的是Redux，它具有单一存储，通常称为单一资料源。

## 未来发展

可以通过核心团队讨论论坛追踪专案状态。但是，对React的重大更改会通过React存储库的未来问题和拉取请求（Pull request）。这使React社群能够就新的潜在功能、实验性API和JavaScript语法改进提供回馈。

## 历史

React由Facebook的软件工程师Jordan Walke建立，他发布了一个名为“FaxJS”的React早期原型。他受到XHP（一个PHP的HTML组件库）的影响。于2011年首次部署在Facebook的News Feed上，随后于2012年部署在Instagram上。于2013年5月在JSConf US宣布开放源代码。

React Native 于2015年2月在Facebook的React Conf上宣布，并于2015年3月开放源代码，支持使用React进行原生Android、iOS和UWP开发。

2017年4月18日，Facebook发布了React Fiber，这是一套新的内部渲染算法，与React的旧渲染算法Stack不同。React Fiber将成为React工具库未来任何改进和功能开发的基础。使用React程式撰写的实际语法不会改变；只有语法的执行方式发生了变化。React的旧渲染系统Stack是在不了解系统对动态变化的关注点的时候开发的。Stack绘制复杂动画的速度很缓慢，例如，试图在一个块中完成所有动画。Fiber将动画分解为可以分布在多个影格上的片段。同样，一个页面的结构可以分解为可以单独维护和更新的片段。JavaScript函数和虚拟DOM对像被称为“纤程”，每个都可以单独操作和更新，从而实现更流畅的屏幕渲染。

2017年9月26日，React 16.0向公众发布。

2019年2月16日，React 16.8向公众发布。该版本导入了React Hooks。

2020年8月10日，React团队宣布了React v17.0的第一个候选版本，值得关注的是第一个主要版本没有对面向React开发人员的API进行重大更改。

2022年3月29日，React 18 向公众发布。该版本引入了新的并行渲染器、自动批次处理，并支援使用 Suspense 进行服务器端渲染。

2024年12月5日，React 19 向公众发布。该版本带来了 Actions 功能，让开发者在使用异步函式来更新状态时，不用再手动处理等待中的状态、错误与乐观更新，整个过程变得更简单。此外 React 19 也支援服务器元件，并改进了静态网站生成功能。

2025年10月，Meta宣布将把React、React Native以及JSX（JavaScript XML）捐赠给新成立的React基金会（React Foundation），该基金会隶属于Linux基金会。2026年2月24日，React 基金会成立，Meta Platforms, Inc. 正式将React专案贡献给该基金会。

2025年11月29日，一项编号为CVE-2025-55182（又名为React2Shell）的漏洞被回报，该漏洞允许攻击者透过React Server Component反序列化协定中的缺陷，进行未经身份验证的远端程式码执行。这个漏洞在CVSS被评定为最高的满分10.0。针对此漏洞的修复已于19.0.1、19.1.2以及19.2.1版本中发布。

2025年12月11日，React团队揭露了React Server Component其他漏洞，包含阻断服务问题（CVE-2025-55184 与 CVE-2025-67779，CVSS 评分为 7.5），以及源代码外泄问题（CVE-2025-55183，CVSS 评分为 5.3）。相关修正已于19.0.4、19.1.5以及19.2.4版本中发布。

## 授权

2013年5月React的首次公开发布使用了Apache License 2.0。2014年10月，React 0.12.0将其更换为3言条款BSD授权条欺，并新增了一个单独的专利授权文件，允许使用与该软件相关的任何Facebook专利：The license granted hereunder will terminate, automatically and without notice, for anyone that makes any claim (including by filing any lawsuit, assertion or other action) alleging (a) direct, indirect, or contributory infringement or inducement to infringe any patent: (i) by Facebook or any of its subsidiaries or affiliates, whether or not such claim is related to the Software, (ii) by any party if such claim arises in whole or in part from any software, product or service of Facebook or any of its subsidiaries or affiliates, whether or not such claim is related to the Software, or (iii) by any party relating to the Software; or (b) that any right in any patent claim of Facebook is invalid or unenforceable.这个不同以往的条款在React用户社群引起了一些争议和争论，因为可以被解释为授权Facebook在许多情况下撤销授权，例如，如果Facebook起诉被授权人通过发布动作来提示他们采取“其他行动”在部落格或其他地方。许多人担心Facebook可能会不公平地利用终止条款，或者将React集成到产品中可能会使新创公司未来的收购变得复杂。

根据社群回馈，Facebook于2015年4月更新了专利授权，以减少歧义并更加宽容：

The license granted hereunder will terminate, automatically and without notice, if you (or any of your subsidiaries, corporate affiliates or agents) initiate directly or indirectly, or take a direct financial interest in, any Patent Assertion: (i) against Facebook or any of its subsidiaries or corporate affiliates, (ii) against any party if such Patent Assertion arises in whole or in part from any software, technology, product or service of Facebook or any of its subsidiaries or corporate affiliates, or (iii) against any party relating to the Software. ... A "Patent Assertion" is any lawsuit or other action alleging direct, indirect, or contributory infringement or inducement to infringe any patent, including a cross-claim or counterclaim.

Apache软件基金会认为这种授权条款安排与其授权政策不相容，因为它“将风险转嫁给我们软件的下游消费者，而不是有利于权利拥有者，而不是权利被被授权者，从而违反了我们作为通用捐助者的Apache法律政策”和“不是 Apache授权2.0 中的子集，它们不能作为 Apache授权2.0 再授权”。2017年8月，Facebook驳回了Apache基金会对下游的担忧，并拒绝重新考虑他们的授权条款。接下来的一个月，WordPress 决定将其Gutenberg和Calypso专案从React中移除。

2017年9月23日，Facebook宣布下周将根据标准MIT授权条款重新授权Flow、Jest、React和Immutable.js；该公司表示，React是“网络开放源代码软件广泛生态系统的基础”，他们不想“因为非技术原因阻碍进展”。

2017年9月26日，React 16.0.0以MIT授权条款发布。MIT授权条款更改也已通过React 15.6.2向后移植到15.x版本线。

## 基本资料

- 作者：Jordan Walke
- 开发者：Meta开源及其社区
- 发行日期：2013年
- 编程语言：JavaScript
- 平台：跨平台
- 类型：JavaScript函式库
- 许可协议：MIT许可证
- 网站：https://react.dev/