React
此条目可参照外语维基百科相应条目来扩充。 |
React(也称为React.js或ReactJS)是一个自由及开放源代码的前端JavaScript工具库,[2] 用于基于UI组件构建用户界面。
原作者 | Jordan Walke |
---|---|
开发者 | Meta开源及其社区 |
首次发布 | 2013年3月 |
当前版本 |
|
源代码库 | github |
编程语言 | JavaScript |
平台 | 跨平台 |
文件大小 | 145 KiB生产版 726 KiB开发版 |
类型 | JavaScript函式库 |
许可协议 | MIT许可证 |
网站 | https://react.dev/ |
它由Meta(前身为Facebook)和由个人开发者和公司组成的社群维护。[3][4][5] React可用作开发具有Next.js等框架的单页、手机或伺服器渲染应用程式的基础。然而,React只专注状态管理和将状态渲染到DOM,因此创建React应用程式通常需要使用额外的工具库来进行路由实作,以及某些客户端功能。[6][7]
基本使用方法
以下是使用JSX和JavaScript在HTML中使用React的基本范例。
import React from "react";
const Greeting = () => {
return (
<div className="hello_world">
<h1> Hello, world! </h1>
</div>
);
};
export default Greeting;
Greeting函数是一个React组件,渲染的结果为“Hello, world”。
在网页浏览器中显示时,结果将是以下内容的渲染:
<div class="hello_world">
<h1>Hello, world!</h1>
</div>
功能
宣告式语法
React采取宣告式程式撰写范式。开发人员为应用程式的每个状态设计视图,React会在资料更改时更新和呈现组件。这与命令式程式撰写不同。[8]
组件
React程式码由称为组件的实体组成。这些组件是可重复利用的,并且必须遵循大写驼峰命名法(Pascal Case)作为其命名规则,也就是大写版本的驼峰式命名法(camelCase)在src资料夹中形成。可以使用React DOM工具库将组件渲染到DOM中的特定元素。渲染组件时,可以通过“props”在组件之间传递参数值:[9]
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。
const Greeter = () => <div>Hello World</div>;
类别组件
基于类的组件使用ES6类别宣告。
class ParentComponent extends React.Component {
state = { color: 'green' };
render() {
return (
<ChildComponent color={this.state.color} />
);
}
}
类别组件都是关于类别的使用和生命周期方法的,而功能组件有Hooks来处理在React中编写代码时出现的状态管理和其他问题。
虚拟DOM
另一个值得注意的特性是使用虚拟文件物件模型(DOM)。React建立一个记忆体资料结构暂存,计算结果差异,然后有效地更新浏览器显示的DOM。[10]这个过程称为reconciliation。这允许程式工程师撰写程式码,就好像每次更改都会渲染整个页面,而React只渲染实际更改的子组件。这种选择性渲染带来了主要的性能提升。[11]节省了重新计算CSS样式、页面排版和渲染整个页面的工作量。[11]
生命周期方法
基于类别组件的生命周期方法使用一种挂钩(Hooking)形式,允许在组件生命周期内的设定点执行程式码。
shouldComponentUpdate
允许开发人员通过在不需要渲染时返回false来防止不必要的组件重新渲染。componentDidMount
只要一旦组件“挂载(mounted)”(组件已在用户界面中建立,通常通过将其与DOM节点关联),就会被呼叫。这通常用于通过API触发从远端资料来源载入资料。componentWillUnmount
在组件被移除或“卸载”(unmounted)之前立即被呼叫。通常用于清除对组件的资源需求相依性模组,这相依性模组不会随著组件的卸载而容易地被删除(例如,删除与组件相关的任何setInterval()
,或设定于“文件”的“事件监听”(eventListener
),因为组件的存在)。render
是最重要的生命周期方法,也是任何组件中唯一需要的方法。它通常在每次组件状态更新时呼叫,也就是应该反映在用户界面中。
JSX
JSX或JavaScript语法扩充,是JavaScript语言语法的扩充。[12] 在外表上与HTML类似,JSX提供了一种使用许多开发人员熟悉的语法来构建组件渲染的方法。React组件通常使用JSX撰写,尽管它们并非必须如此(组件也可以使用纯JavaScript撰写)。JSX类似于Facebook为PHP创建的另一个扩展语法,称为XHP。
JSX代码范例:
class App extends React.Component {
render() {
return (
<div>
<p>Header</p>
<p>Content</p>
<p>Footer</p>
</div>
);
}
}
嵌套的元素
同一层级上的多个元素需要包装在一个React元素中。例如上面代码中,<p>
被包裹在 <div>
元素中。否则需要由 <Fragment>
或其简写形式 <>
包围,或作为数组返回。[13]
HTML之外的架构
React的基本架构不仅适用于在浏览器中呈现HTML。例如,Facebook有渲染到<canvas>
标签,[14] Netflix 和 PayPal 使用通用载入于伺服器和客户端上渲染相同的HTML。[15][16]
React hooks
Hooks是让开发人员从函数组件中“钩入(Hook into)”React状态和生命周期特性的函数。Hooks在类别组件无法作用——它们让你在没用类别组件情况下使用React。[17]
React提供了一些内建的Hook,例如 useState
,[18]useContext
、useReducer
、useMemo
与useEffect
。[19] 其他的记录在Hooks API参考中。[20] useState
与useEffect
,也就是最常用,分别用于状态和副作用的控制。
Hooks的使用规范
下面有一些Hooks规范[21] 描述了钩子(Hooks)的特征程式码模式,也是现今使用React处理状态方式。
- Hooks只能在顶层呼叫(而不是在回圈或if语句内)。
- Hooks只能从React函数组件和自定义Hooks呼叫,而不是普通函数或类别组件。
虽然这些规范不能在执行时强制执行,但可以设定程式码分析工具(例如linter)来侦测开发过程中的许多错误。
这些规范适用于Hooks的使用和自定义Hooks的实作,[22] 也就是可能会调用其他Hooks。
常用惯用语
React并不刻意提供一个完整的“应用程式工具库”。专为构建用户界面而设计,因此不包含一些开发人员可能认为构建应用程序所必需的许多工具。这也允许选择开发人员喜欢的任何工具库来完成诸如执行网路访问或本地资料存储等任务。随著工具库的成熟,常见的使用模式已经出现。
单向资料流
为了支援React的单向资料流概念(可能与 AngularJS 的双向资料流形成对比),Flux架构被开发为流行的模型-视图-控制器架构的替代方案。Flux具有通过中央调度程式发送到储存区(Store)的操作,并且对储存区的更改被传递回视图。[23] 当与React一起使用时,这种传递是通过组件属性完成的。从Flux的概念开始,Flux就被Redux和MobX等工具库所取代。[24]
Flux架构下的React组件不应直接修改传递给它的任何props,而应传递回调函数,这些回呼函数创建由调度程式发送的用于修改存储的操作。动作(Action)是一个对象,负责描述发生的事情:例如,描述一个用户“关注”另一个用户的动作可能包含用户ID、目标用户ID和类型USER_FOLLOWED_ANOTHER_USER
。可以将存储视为模型,可以根据从调度程式接收到的操作来改变自己。
这种模式有时表示为“属性(Properties)向下流动,动作(Actions)向上流动”。Flux的许多实作从一开始就被建立了,也许最著名的是Redux,它具有单一存储,通常称为单一资料源。[26]
未来发展
可以通过核心团队讨论论坛追踪专案状态。[27] 但是,对React的重大更改会通过React存储库的未来问题和拉取请求(Pull request)。[28][29] 这使React社群能够就新的潜在功能、实验性API和JavaScript语法改进提供回馈。
历史
React由Facebook的软体工程师Jordan Walke建立,他发布了一个名为“FaxJS”的React早期原型。[30][31] 他受到XHP(一个PHP的HTML组件库)的影响。于2011年首次部署在Facebook的News Feed上,随后于2012年部署在Instagram上。[32] 于2013年5月在JSConf US宣布开放原始码。[31]
React Native 于2015年2月在Facebook的React Conf上宣布,并于2015年3月开放原始码,支持使用React进行原生Android、iOS和UWP开发。
2017年4月18日,Facebook发布了React Fiber,这是一套新的内部渲染演算法,与React的旧渲染演算法Stack不同。React Fiber将成为React工具库未来任何改进和功能开发的基础。[33][已过时] 使用React程式撰写的实际语法不会改变;只有语法的执行方式发生了变化。[34] React的旧渲染系统Stack是在不了解系统对动态变化的关注点的时候开发的。Stack绘制复杂动画的速度很缓慢,例如,试图在一个块中完成所有动画。Fiber将动画分解为可以分布在多个影格上的片段。同样,一个页面的结构可以分解为可以单独维护和更新的片段。JavaScript函数和虚拟DOM对像被称为“纤程”,每个都可以单独操作和更新,从而实现更流畅的屏幕渲染。[35]
2017年9月26日,React 16.0向公众发布。[36]
2019年2月16日,React 16.8向公众发布。[37] 该版本导入了React Hooks。[38]
2020年8月10日,React团队宣布了React v17.0的第一个候选版本,值得关注的是第一个主要版本没有对面向React开发人员的API进行重大更改。[39]
授权
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集成到产品中可能会使新创公司未来的收购变得复杂。[40]
根据社群回馈,Facebook于2015年4月更新了专利授权,以减少歧义并更加宽容:[41]
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.[42]
Apache软件基金会认为这种授权条款安排与其授权政策不相容,因为它“将风险转嫁给我们软体的下游消费者,而不是有利于权利拥有者,而不是权利被被授权者,从而违反了我们作为通用捐助者的Apache法律政策”和“不是 [Apache授权2.0] 中的子集,它们不能作为 [Apache授权2.0] 再授权”。[43] 2017年8月,Facebook驳回了Apache基金会对下游的担忧,并拒绝重新考虑他们的授权条款。[44][45] 接下来的一个月,WordPress 决定将其Gutenberg和Calypso专案从React中移除。[46]
2017年9月23日,Facebook宣布下周将根据标准MIT授权条款重新授权Flow、Jest、React和Immutable.js;该公司表示,React是“网络开放原始码软体广泛生态系统的基础”,他们不想“因为非技术原因阻碍进展”。[47]
2017年9月26日,React 16.0.0以MIT授权条款发布。[48] MIT授权条款更改也已通过React 15.6.2向后移植到15.x版本线。[49]
参见
参考资料
- ^ https://registry.npmjs.com/react.
- ^ React - A JavaScript library for building user interfaces.. React. [7 April 2018]. (原始内容存档于2022-04-11).
- ^ Krill, Paul. React: Making faster, smoother UIs for data-driven Web apps. InfoWorld. May 15, 2014 [2022-05-19]. (原始内容存档于2018-06-12).
- ^ Hemel, Zef. Facebook's React JavaScript User Interfaces Library Receives Mixed Reviews. InfoQ. June 3, 2013 [2022-05-19]. (原始内容存档于2018-06-12).
- ^ Dawson, Chris. JavaScript's History and How it Led To ReactJS. The New Stack. July 25, 2014 [2022-05-19]. (原始内容存档于2018-06-12).
- ^ Dere, Mohan. How to integrate create-react-app with all the libraries you need to make a great app. freeCodeCamp. 2018-02-19 [2018-06-14].
- ^ Angular vs React Detailed Comparison. Groovy Web. 2018-02-19 [2022-04-25]. (原始内容存档于2022-05-31).
- ^ Schwarzmüller, Max. React - The Complete Guide. O'Reilly. Packt Publishing. [19 February 2022]. (原始内容存档于2022-05-31).
- ^ Components and Props. React. Facebook. [7 April 2018]. (原始内容存档于2022-08-07).
- ^ Refs and the DOM. React Blog. [2022-05-19]. (原始内容存档于2022-08-07).
- ^ 11.0 11.1 React: The Virtual DOM. Codecademy. [2021-10-14]. (原始内容存档于2021-10-28) (英语).
- ^ Draft: JSX Specification. JSX. Facebook. [7 April 2018]. (原始内容存档于2022-04-02).
- ^ React v16.0 – React Blog. legacy.reactjs.org. [2023-07-07]. (原始内容存档于2023-10-03) (英语).
- ^ Why did we build React? – React Blog. [2022-05-19]. (原始内容存档于2015-04-06).
- ^ PayPal Isomorphic React. (原始内容存档于2019-02-08).
- ^ Netflix Isomorphic React. [2022-05-19]. (原始内容存档于2016-12-17).
- ^ What the Heck is React Hooks?. Soshace. 2020-01-16 [2020-01-24]. (原始内容存档于2022-05-31) (英语).
- ^ Using the State Hook – React. reactjs.org. [2020-01-24]. (原始内容存档于2022-07-30) (英语).
- ^ Using the Effect Hook – React. reactjs.org. [2020-01-24]. (原始内容存档于2022-08-01) (英语).
- ^ Hooks API Reference – React. reactjs.org. [2020-01-24]. (原始内容存档于2022-08-05) (英语).
- ^ Rules of Hooks – React. reactjs.org. [2020-01-24]. (原始内容存档于2021-06-06) (英语).
- ^ Building Your Own Hooks – React. reactjs.org. [2020-01-24]. (原始内容存档于2022-07-17) (英语).
- ^ In Depth OverView. Flux. Facebook. [7 April 2018]. (原始内容存档于2022-08-07).
- ^ Flux Release 4.0. Github. [26 February 2021]. (原始内容存档于2022-05-31).
- ^ Johnson, Nicholas. Introduction to Flux - React Exercise. Nicholas Johnson. [7 April 2018]. (原始内容存档于2022-05-31).
- ^ State Management Tools - Results. The State of JavaScript. [29 October 2021]. (原始内容存档于2022-05-31).
- ^ Meeting Notes. React Discuss. [2015-12-13]. (原始内容存档于2015-12-22).
- ^ reactjs/react-future - The Future of React. GitHub. [2015-12-13]. (原始内容存档于2022-07-13).
- ^ facebook/react - Feature request issues. GitHub. [2015-12-13]. (原始内容存档于2022-07-09).
- ^ Walke, Jordan. FaxJS. [11 July 2019]. (原始内容存档于2021-12-16).
- ^ 31.0 31.1 Papp, Andrea. The History of React.js on a Timeline. RisingStack. 4 April 2018 [11 July 2019]. (原始内容存档于2022-05-31).
- ^ Pete Hunt at TXJS. [2022-05-19]. (原始内容存档于2017-07-31).
- ^ React Fiber Architecture. Github. [19 April 2017]. (原始内容存档于2018-05-10).
- ^ Facebook announces React Fiber, a rewrite of its React framework. TechCrunch. [2018-10-19]. (原始内容存档于2018-06-14).
- ^ GitHub - acdlite/react-fiber-architecture: A description of React's new core algorithm, React Fiber. github.com. [2018-10-19]. (原始内容存档于2018-05-10).
- ^ React v16.0. react.js. 2017-09-26 [2019-05-20]. (原始内容存档于2022-07-14).
- ^ React v16.8. react.js. 2019-02-16 [2019-05-20]. (原始内容存档于2022-07-14).
- ^ Introducing Hooks. react.js. [2019-05-20]. (原始内容存档于2022-08-03).
- ^ url=https://reactjs.org/blog/2020/08/10/react-v17-rc.html (页面存档备份,存于互联网档案馆)
- ^ Liu, Austin. A compelling reason not to use ReactJS. Medium. [2022-05-19]. (原始内容存档于2022-05-31).
- ^ Updating Our Open Source Patent Grant. [2022-05-19]. (原始内容存档于2020-11-08).
- ^ Additional Grant of Patent Rights Version 2. GitHub. [2022-05-19]. (原始内容存档于2022-05-31).
- ^ ASF Legal Previously Asked Questions. Apache Software Foundation. [2017-07-16]. (原始内容存档于2018-02-06) (英语).
- ^ Explaining React's License. Facebook. [2017-08-18]. (原始内容存档于2021-05-06) (英语).
- ^ Consider re-licensing to AL v2.0, as RocksDB has just done. Github. [2017-08-18]. (原始内容存档于2022-07-27) (英语).
- ^ WordPress to ditch React library over Facebook patent clause risk. TechCrunch. [2017-09-16]. (原始内容存档于2022-05-31) (英语).
- ^ Relicensing React, Jest, Flow, and Immutable.js. Facebook Code. 2017-09-23 [2022-05-19]. (原始内容存档于2020-12-06) (英语).
- ^ Clark, Andrew. React v16.0§MIT licensed. React Blog. September 26, 2017 [2022-05-19]. (原始内容存档于2022-07-14).
- ^ Hunzaker, Nathan. React v15.6.2. React Blog. September 25, 2017 [2022-05-19]. (原始内容存档于2022-05-31).