React 技术专题简介-冯金伟博客园

简介

React原作者Jordan Walke开发者Meta开源及其社区首次发布2013年3月,​10年前​(2013-03)当前版本18.2.0 (2022年6月14日;稳定版本) 源代码库github.com/facebook/react编程语言JavaScript系统平台跨平台文件大小145 KiB生产版726 KiB开发版类型JavaScript库许可协议MIT许可证网站ar.reactjs.org/ React(也称为React.js或ReactJS)是一个自由及开放源代码的前端JavaScript工具库, 用于基于UI组件构建用户界面。它由Meta(前身为Facebook)和由个人开发者和公司组成的社群维护。React可用作开发具有Next.js等框架的单页、手机或服务器渲染应用程序的基础。然而,React只专注状态管理和将状态渲染到DOM,因此创建React应用程序通常需要使用额外的工具库来进行路由实现,以及某些客户端功能。

基本使用方法

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

import React from "react";const Greeting = () => {  return (          

Hello, world!

);};export default Greeting;

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

在网A浏览器中显示时,结果将是以下内容的渲染:

  

Hello, world!

功能

宣告式语法

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

组件

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

import React from "react";import Tool from "./Tool";const Example = () => {  return (                            

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

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

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

函数组件

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

const Greeter = () => Hello World;

类别组件

基于类的组件是使用ES6类声明。

class ParentComponent extends React.Component {  state = { color: 'green' };  render() {    return (          );  }}

类别组件都是关于类别的使用和生命周期方法的,而功能组件有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代码示例:

class App extends React.Component {  render() {    return (              

Header

Content

Footer

); }}

HTML之外的架构

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

React hooks

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

React提供了一些内置的Hook,例如 useState,useContextuseReduceruseMemouseEffect。 其他的记录在Hooks API参考中。 useStateuseEffect,也就是最常用,分别用于状态和副作用的控制。

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进行重大更改。

许可

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法律政策”和“不是 中的子集,它们不能作为 再许可”。 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版本线。