React相关知识点零散记录
作者:互联网
React
- 从react16.8之后,出现了fiber链表,将递归渲染组件树变成可打断的渲染(使用链表串联关系),他是一个承载各种节点信息的工作单元,也是一个对象
- 一开始function组件没有状态,通过fiber节点添加
memorizedState
属性用来存储数据,然后在 function 组件里面通过 api 来使用这些数据,这些 api 被叫做 hooks api。(学习阶段可以用Array+Cursor模拟) - hook api用链表存放数据,所以要保证数据顺序不变,所以hook api不能出现在if等逻辑块中,只能在顶层。
fiber的数据结构中的memoizedState
是指向属于这个fiber的hooks链表的首个hook,hook中的memoizedState
是当前hook所缓存的state值。function 组件有多个hooks,链表就多长。
“所有 hooks api 都是基于 fiber 节点上的 memorizedState 链表来存取数据并完成各自的逻辑的。”
hook effects被存储在fiber的updateQueue属性上,每个effect内部利用tag(二进制位)标记是什么类型的effect
hook对象的基本结构
{
memoizedState:null, //储存usestate 值
baseState:null, // 每次更新产生的值
baseQueue:null, // 当前的队列
queue: null , // 更新队列 保存负责更新的事件
next: null, // 指向下一个hook
}
useRef useCallback useMemo
三个hook源码都比较简单。在创建链表阶段(mount),在链表(hook)的memoizedState属性上添加值。在更新阶段 通过获取当前链表(hook),进行判断。不涉及到调度逻辑,只是单纯的缓存了下值。
Fiber
react内部运转分三层:
- Virtual DOM 层,描述页面长什么样。
- Reconciler 层,负责调用组件生命周期方法,进行 Diff 运算等。
- Renderer 层,根据不同的平台,渲染出相应的页面,比较常见的是 ReactDOM 和 ReactNative。
为了实现不卡顿,就需要有一个调度器 (Scheduler) 来进行任务分配。优先级高的任务(如键盘输入)可以打断优先级低的任务(如Diff)的执行,从而更快的生效。任务的优先级有六种:
- synchronous,与之前的Stack Reconciler操作一样,同步执行
- task,在next tick之前执行
- animation,下一帧之前执行
- high,在不久的将来立即执行
- low,稍微延迟执行也没关系
- offscreen,下一次render时或scroll时才执行
Fiber Reconciler(react )执行过程分为2个阶段:
- 阶段一,生成 Fiber 树,得出需要更新的节点信息。这一步是一个渐进的过程,可以被打断。阶段一可被打断的特性,让优先级更高的任务先执行,从框架层面大大降低了页面掉帧的概率。
- 阶段二,将需要更新的节点一次过批量更新,这个过程不能被打断。
从Stack Reconciler到Fiber Reconciler,源码层面其实就是干了一件递归改循环的事情
React事件监听原理
事件并不是绑定在真实DOM上,而是在document监听事件,当事件冒泡至document时处理:react将事件封装再交给处理函数运行。方便订阅和消除事件,也减少内存消耗。
面试
useEffect和useLayouteffect区别
useEffect
不会阻塞浏览器渲染,而useLayoutEffect
会阻塞浏览器渲染。useEffect
会在浏览器渲染结束后执行,useLayoutEffect
则是在DOM
更新完成后,浏览器绘制之前执行。
合成事件和原生事件
React 中 setState 什么时候是同步的,什么时候是异步的?
https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/17
Hook常见问题
hook闭包陷阱(过时的闭包)
使用React。useRef创建一个引用对象,读写都在这个ref就能获取最新值
https://juejin.cn/post/7034695882347905060#heading-2
标签:知识点,零散,api,链表,React,hook,fiber,执行,Reconciler 来源: https://www.cnblogs.com/hejiyuan/p/16364712.html