第01章 课程导学
01-01 课程导学
一、UI=fn(x)
核心api:setState
没有directive双向绑定
二、vue,angular更新大版本,需要调整兼容
三、react,引入fiber,从根本上解决了,js单线程运行,如果计算量太大,导致动画卡帧,交互卡顿问题
四、第1章:React API,及每个API的作用
createElement、createContext、JSX=>JS、ConcurrentMode、Ref、Component、Suspense、Hooks
五、第2章:React中的更新创建
ReactDOM.render、Fiber、UpdateQueue、FiberRoot、Update、expirationTime
六、第3章:react创建完,更新之后的调度过程
scheduleWork、batchedUpdates、performWork、performUnitOfWork、requestWork、react scheduler、renderRoot
七、第4章:开始更新
beginWork以及优化、各类组件的更新过程、调和子节点的过程
八、第5章:完成各个节点的更新
completeUnitOfWork、completeWork、unwindWork、虚拟DOM对比、错误捕获处理、完成整棵树更新
九、第6章:提交更新
commitRoot整体流程、提交快照、提交DOM更新、提交所有声明周期、开发时的帮助方法、提交DOM插入、提交DOM删除
十、第7章:各种功能的实现过程
context的实现过程、ref的实现过程、hydrate的实现过程、React的事件体系
十一、第8章:Suspense
优先更新级的概念、Suspense组件更新、retry重新尝试渲染、更新挂起的概念、timeout处理、lazy组件更新
十二、第9章:Hooks
核心原理、useState、useEffect、useContext、其他Hooks API
十三、Fiber、Update、Scheduler等核心着重讲解
十四、课程电子书链接:https://react.jokcy.me/book/api/react.html
十五、通读源码
外在:提高开发能力、解决问题的能力、提升自身价值
内在:提升学习能力、提升思考能力、提升设计能力
第02章 基础知识React api 一览
02-01 准备工作
一、目录结构
1、packages/
(1)event/
react 事件系统, onClick,自己实现了一套事件传播系统,区别于原生的事件绑定
(2)react/
react包全都在这里
(3)react-dom/
npm安装时,react-dom的源文件包
react-dom会重度依赖react-reconciler
(4)react-reconciler
独立的公共源码
二、react、react-dom之间的关系
1、jsx是与react相关的
2、react本身是一种定义,表现行为的包
3、如何渲染,如何更新都是在react-dom中
三、Flow Type
1、flow,静态检查工具,强制性没有typescript那么高
import type { ReactNodeList } from 'shared/ReactTypes'
2、对代码阅读不会产生太大影响。
3、官网文档:https://flow.org
02-02 JSX到JavaScript的转换
一、babel转换地址(代码转换的测试):https://babeljs.io/repl
02-03 react-element
一、ReactElement.js
export function createElement( type, config, children) { }
二、react提供的原生组件:Fragment、StrictMode、Suspense
三、config
写在jsx标签上所有的attrs,筛选出props,特殊的key, ref
是否是内建的props
02-07 context
一、组件与组件之间的共同,父子组件沟通,用props
二、context两种方式
childContextType,将在react 17版本中废弃
createContext
三、childContextType
每次更新,都需要进行完整的渲染,对性能消耗非常大
02-08 ConcurrentMode
一、让react的整体渲染过程,能进行一个优先级的排序,并且让整体的渲染过程能中断。这样就可以进行一个任务的调度,提高cpu性能。
如果react更新占用js进程,动画,或input响应就会比较卡。
二、flushSync, import { flushSync } from ‘react-dom’
在更新操作的时候,使用优先级最高的方式去进行更新。
三、如果用了ConcurrentMode,它的子组件产生的更新都是低优先级更新。
02-09 Suspense and lazy
一、Suspense下渲染一个或多个组件,子组件throw promise之前,都会用fallback里的内容
二、16.6只支持lazy,就是异步加载组件,没有支持异步数据加载。
三、在Suspense内部,要等到所有组件都resolve之后,才会把fallback去掉,然后显示里面的内容。有任何一个处于Pending状态的,都会显示fallback
<Suspense>
<SuspenseComp />
<LazyComp />
</Suspense>
02-10 Hooks
一、hooks的react, react-dom要在16.7版本以上
二、function Component,没有this对象,不能使用生命周期方法
三、React Conf视频:https://reactjs.bootcss.com/blog/2018/11/13/react-conf-recap.html
(讲解了为什么要用hooks)
四、hooks里没有着重区分mounted和updated
五、useEffect,解除绑定用return
useEffect(() => {
console.log('component update')
return () => {
console.log('component unbind')
}
}, [])
02-11 children
一、React.children
二、实际跟数组的map, forEach有点差别
Children: {
map,
forEach,
count,
toArray,
only,
}
map有返回,返回新的数组;forEach无返回,还是原来的数组。
三、
import React from 'react'
function ChildrenDemo (props) {
console.log(props.children)
// [child1, 1, 1, 2, 2, 2]
console.log(React.children.map(props.children, c=> [c, [c, [c]]])) // map方法,变成一维数组
return props.children
}
export default () => {
<ChildrenDemo>
<span>1</span>
<span>1</span>
</ChildrenDemo>
}
四、添加对象,删除对象,可能会引起内存抖动问题
五、关于key相关的东西,children打印出来,会有key,怎么实现的
getComponentKey
02-12 others
一、memo
16.6推出的api,给function component,有PureComponent类似的功能(提供了class component 组件类型)
forwardRef
context差不多的东西
二、Fragment
<></>
, 同<React.Fragment></React.Fragment>
三、StrictMode
标记着这个节点上的所有子元素,会给一些过时的api的提醒
四、cloneElement
创建一个新的reactElement
五、createFactory
对于jsx,基本不可能用到
是对createElement的封装,是createElement绑定了一个type
第03章 react中的更新
03-01 react-dom-render
一、创建更新的方式
ReactDOM.render || hydrate
setState
forceUpdate
二、步骤
创建ReactRoot
创建FiberRoot和RootFiber
创建更新
三、demo
三、ReactDom.render(), 传进去的<App />
是类,并不是实例
四、updateContainerAtExpirationTime(),react16很重要的内容
react16之后,提供了任务优先级(scheduleWork)的概念。这是react中最复杂的内容
03-02 react-fiber-root
一、什么是FiberRoot
整个应用的起点
包含应用挂载的目标节点
记录整个应用更新过程的各种信息
二、createFiberRoot,return 了一个对象
03-03 react-fiber
一、什么是Fiber
1、每一个ReactElement对应一个Fiber对象
2、记录节点的各种状态(state, props都是记录在Fiber上的)
本身记录节点状态不是在class component上,而是在fiber上,所以可以用在PureComponent
3、串联整个应用形成树结构
二、effect,副作用,标记最终更新的内容
三、创建对象消耗性能比较大,alternate属性:提高性能的
03-04 react-update-and-updateQueue
一、什么是Update
用于记录组件状态的改变
存放于UpdateQueue中
多个Update可以同时存在
二、react16之后有ErrorBoundary的功能
03-05 react-expiration-time
一、| 0表示取整
(ms / UNIT_SIZE) | 0
二、computeExpirationForFiber(currentTime, current)
computeExpirationBucket
03-06 different-expiration-time
一、异步任务可以随便被打断。如果某个任务过了expiration-time,都没有被执行,则强制执行
二、种类
Sync模式:创建即更新的流程
异步模式:调度,可能会被打断
指定context
三、二进制,通过与&、或|,能很好地进行判断、操作
03-07 react setState forceUpdate
一、ReactDOM.render, setState, forceUpdate去更新组件状态
二、setState, forceUpdate 核心
1、给节点的Fiber创建更新
2、更新的类型不同
三、const classComponentUpdater
enqueueSetState
enqueueForceUpdate
与updateContainer方法特别像
四、react,创建更新的过程都差不多
第04章 fiber scheduler
04-01 总结流程概览
一、ReactFIberSchedule,调度
很多公共变量名
二、scheduleDefferredCallback
1、期望用的是requestIdleCallback(https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestIdleCallback),但是兼容性不高
2、通过【浏览器的requestAnimatIon,js任务队列的原理进行模拟】实现
04-02 ScheduleWork
一、核心知识点
找到更新对应的FiberRoot节点
如果符合条件重置stack
如果符合条件就请求工作调度
04-03 requestWork
一、核心知识点
1、加入到root调度队列
2、判断是否批量更新
3、根据expirationTime判断调度类型
04-04 batchedUpdates
一、setState后console.log出来的state值并不是最新的,batchedUpdates
二、create-react-app创建的项目,node_modules的改变并不会自动更新浏览器内容,需要重启项目
三、更新队列,一个方法中,每次的更新都放到一个队列中,最终完成之后才会更新最终值。
四、setTimeout改变了上下文环境,会导致应用整体性能下降
batchUpdates也是改变了上下文环境
五、面试题:setState是同步的还是异步的?
setState本身的方法调用是同步的,但是调用了setState并不标志着react的state会立马就更新,这个更新是根据我们当前环境的执行上下文来判断的。如果处于批量更新的情况下,那么state不是当前立马更新的。而如果我不处于批量更新的情况下,它就有可能是立马更新的。
那为什么我要说是有可能呢,因为我们现在是有sync module, context module这种异步渲染的情况。如果我处于异步渲染的情况下,我这个state也不是立马就更新的。因为我们之前讲过了,进入异步更新的话,它要进入一个异步的调度的过程,这个过程肯定不会立马更新state
04-05 react scheduler(1),异步调度
一、核心知识点
1、维护时间片
2、模拟requestIdleCallback
调用这个api,传入一个回调,这个api会等浏览器把其他任务执行完了,等javascript运行有空闲的时候,再回来调用这个回调
requestAnimationFrame,浏览器要渲染当前帧的时候,就执行这个回调
3、调度列表和超时判断
二、如果要给用户流畅的感觉,1秒钟至少要刷新30次(平均)