React学习知识点之原理

324 阅读3分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

JSX

  • 是JavaScript的扩展语法,React使用它来描述用户界面长成什么样子,虽然它看起来非常像HTML,但它确实是JavaScript,在React代码执行之前,Bebal会将JSX编码为React API

  • 是单标记,必须闭合,否则报错

单向数据流

  • 自顶向下,从父组件到子组件

  • 单向数据流要求我们共享数据要放在上层组件中

  • 子组件通过调用父组件传递过来的方法更改数据

  • 当数据发生更改时,React会重新渲染组件树

  • 单向数据流使组件之间的数据流向变得可预测,使得定位程序变得简单

VirtualDOM

Diff算法

两个元素进行对比时,如果类型相同,就循环旧的DOM对象的子元素,查看其身上是否有key属性,如果有就将这个子元素的DOM对象存储在一个JavaScript对象中,接着循环要渲染的VirtualDom对象的子元素,在循环过程中获取到这个子元素的key属性,然后使用这个key属性到JavaScript对象中查找DOM对象,如果能找到说明这个元素是存在的,是不需要重新渲染的,如果找不到说明这个元素是新增的需要渲染。

ref

  • 类组件的ref,是用来获取组件的实例对象

  • 节点的ref属性用来获取这个节点的DOM对象

key

是数据的唯一标识,帮助react识别哪些数据被修改或者删除了,从而达到DOM最小化操作的目的。

key属性不需要全局唯一,但是在同一个父节点下的兄弟节点之间必须是唯一的

Fibber

为什么出现Fibber

React 16之前的版本对比更新VirtualDOM的过程是采用循环加递归实现的,这种对比范式一旦任务开始就无法终端,如果应用中组件数量庞大,主线程被长期占用,直至整颗VirtualDOM树比对更新完成之后主线程才能被释放,主线程才能执行其他任务。这就会导致一些用户交互、动画等任务无法立即得到执行,页面就会产生卡顿,影响用户体验。

核心问题:递归无法中断,执行重任务耗时长。JavaScript又是单线程,导致任务延迟页面卡顿,用户体验差

特点
  • 利用浏览器空闲时间执行任务,拒绝长时间占用主线程

  • 放弃递归只采用循环,因为循环可以被中断

  • 任务拆分,将任务拆分成一个个的小任务

fibber对象
{
  type         节点类型 (元素, 文本, 组件)(具体的类型)
  props        节点属性
  stateNode    节点 DOM 对象 | 组件实例对象
  tag          节点标记 (对具体类型的分类 hostRoot || hostComponent || classComponent || functionComponent)
  effects      数组, 存储需要更改的 fiber 对象
  effectTag    当前 Fiber 要被执行的操作 (新增, 删除, 修改)
  parent       当前 Fiber 的父级 Fiber
  child        当前 Fiber 的子级 Fiber
  sibling      当前 Fiber 的下一个兄弟 Fiber
  alternate    Fiber 备份 fiber 比对时使用
}