React学习笔记

182 阅读6分钟

React学习笔记

一. React介绍

1. React起源于发展

React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在 2013 年 5 月开源了。

💡 Fecebook是真的牛,我不满意,我自己写一个

2.React与传统MVC的关系

react是什么?其官网给出了明确定义: AJavaScriptlibraryforbuilding user interfaces ,一个用于构建用户界面的JavaScript库。

MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

Untitled.png 前端代表的框架有:AngularJS、BackboneJS、Ember、React、Knockout 等。

但 React 并不是完整的 MVC 框架,一般更偏向 View 层。将界面分割成每个独立的组件与模块,再相互组合、嵌套成一个完整页面。

3. React的特性

特点:

  1. 声明式设计:React采用生命范式,可以轻松描述应用。
  2. 高效:React通过对DOM的模拟,最大限度的减少与DOM的交互。
  3. 灵活:React可以与已知的库或框架很好的配合
  4. JSX—JSX是javascript语法的扩展。
  5. 组件—通过React构建组件,使得代码更加容易复用,能够很好的应用在大项目的开发中。
  6. 单向数据流—React实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更加简单

4.虚拟DOM

Untitled 1.png

传统Dom更新:

真实页面对应一个DOM树,在传统的 Web 应用中,我们往往会把数据的变化实时地更新到用户界面中,于是每次数据的微小变动都会引起 DOM 树的重新渲染。虚拟DOM的目的是将所有操作累加起来,统计计算出所有的变化后,统一更新一次DOM。

React diff算法

当Node节点的更新,虚拟DOM会比较两棵DOM树的区别,保证最小化的DOM操作,使得执行效率得到保证。计算两棵树的常规算法是O(n^3)级别,所以需要优化深度遍历的算法。React diff算法的时间复杂度为O(n)

Untitled 2.png

React 分别对 tree diff、component diff以及 element diff 进行算法优化

💡 tree dif

Untitled 3.png

DOM 节点跨层级的移动操作少到可以忽略不计,针对这一现象,React 通过 updateDepth 对 Virtual DOM 树进行层级控制,只会对相同颜色方框内的 DOM 节点进行比较,即同一个父节点下的所有子节点。当发现节点已经不存在,则该节点及其子节点会被完全删除掉,不会用于进一步的比较。这样只需要对树进行一次遍历,便能完成整个 DOM 树的比较。

💡 component diff

如果是同一类型的组件,按照原策略继续比较 virtual DOM tree,如果不是,则将该组件判断为 dirty component,从而替换整个组件下的所有子节点。对于同一类型的组件,有可能其 Virtual DOM 没有任何变化,如果能够确切的知道这点那可以节省大量的 diff 运算时间,因此 React 允许用户通过 shouldComponentUpdate() 来判断该组件是否需要进行 diff。

Untitled 4.png

当 component D 改变为 component G 时,即使这两个 component 结构相似,一旦 React 判断 D 和 G 是不同类型的组件,就不会比较二者的结构,而是直接删除 component D,重新创建 component G 以及其子节点。

💡 element diff

节点处于同一层级时,React diff 提供了三种节点操作,分别为:INSERT_MARKUP(插入)、MOVE_EXISTING(移动)和 REMOVE_NODE(删除)。

Untitled 5.png

新老集合所包含的节点,如下图所示,新老集合进行 diff 差异化对比,通过 key 发现新老集合中的节点都是相同的节点,因此无需进行节点删除和创建,只需要将老集合中节点的位置进行移动,更新为新集合中节点的位置,此时 React 给出的 diff 结果为:B、D 不做任何操作,A、C 进行移动操作,即可。

总结

  1. React 通过制定大胆的 diff 策略,将 O(n3) 复杂度的问题转换成 O(n) 复杂度的问题;
  2. React 通过分层求异的策略,对 tree diff 进行算法优化;
  3. React 通过相同类生成相似树形结构,不同类生成不同树形结构的策略,对 component diff 进行算法优化;
  4. React 通过设置唯一 key的策略,对 element diff 进行算法优化;

二. 创建自己的React项目

  1. 确保你安装了较新版本的 Node.js
  2. 按照 Create React App 安装指南 创建一个新的项目

全局安装指令

npm install -g create-react-app

创建一个项目

create-react-app your-app //注意命名方式

如果不想全局安装,可直接食用npx

npx create-react-app myapp //可实现相同的效果

安装需要等待一段时间,这个过程实际上会安装三个东西

  • react : react的顶级库
  • react-dom:因为react有很多的运行环境,比如app端的raect-native,我们要在web上运行就使用react-dom
  • react-scripts:包含运行和打包react应用程序的所有脚本及配置

出现下面的界面,代表 项目创建成功

Success! Created your-app at /dir/your-app
Inside that directory, you can run several commands:
npm start
Starts the development server.
npm run build
Bundles the app into static files for production.
npm test
Starts the test runner.
npm run eject
Removes this tool and copies build dependencies, configuration files
and scripts into the app directory. If you do this, you can’t go back!
We suggest that you begin by typing:
cd your-app
npm start
Happy hacking!

根据上面的提示,通过cd your-app命令进入目录并运行 npm start 即可运行项目

生成的项目目录结构如下:

├── README.md 使用方法的文档
├── node_modules 所有的依赖安装的目录
├── package-lock.json 锁定安装时的包的版本号,保证团队的依赖能保证一致。
├── package.json
├── public 静态公共目录
└── src 开发用的源代码目录

常见问题:

npm安装失败 切换为npm镜像为淘宝镜像 使用yarn,如果本来使用yarn还要失败,还得把yarn的源切换到国内 如果还没有办法解决,请删除node_modules及package-lock.json然后重新执行 npm install命令 再不能解决就删除node_modules及package-lock.json的同时清除npm缓存 npm cache clean --force 之后再执行 npm install 命令