人人都能读懂的react源码解析(大厂高薪必备)
12.手写迷你react(短小精悍就是我)
视频课程&调试demos
视频课程的目的是为了快速掌握react源码运行的过程和react中的scheduler、reconciler、renderer、fiber等,并且详细debug源码和分析,过程更清晰。
视频课程:进入课程
demos:demo
课程结构:
- 开篇(听说你还在艰难的啃react源码)
- react心智模型(来来来,让大脑有react思维吧)
- Fiber(我是在内存中的dom)
- 从legacy或concurrent开始(从入口开始,然后让我们奔向未来)
- state更新流程(setState里到底发生了什么)
- render阶段(厉害了,我有创建Fiber的技能)
- commit阶段(听说renderer帮我们打好标记了,映射真实节点吧)
- diff算法(妈妈再也不担心我的diff面试了)
- hooks源码(想知道Function Component是怎样保存状态的嘛)
- scheduler&lane模型(来看看任务是暂停、继续和插队的)
- concurrent mode(并发模式是什么样的)
- 手写迷你react(短小精悍就是我)
迷你react和真正的源码有哪些区别呢
- 在render阶段我们遍历了整颗Fiber树,在源码中如果节点什么都没改变会命中优化的逻辑,然后跳过这个节点的遍历
- commit我们也遍历了整颗Fiber树,源码中只遍历带有effect的Fiber节点,也就是遍历effectList
- 每次遍历的时候我们都是新建节点,源码中某些条件会复用节点
- 没有用到优先级
第一步:渲染器和入口函数
const React = {
createElement,
render,
}
const container = document.getElementById("root")
const updateValue = e => {
rerender(e.target.value)
}
const rerender = value => {
const element = (
<div>
<input onInput={
updateValue} value={
value} />
<h2>Hello {
value}</h2>
</div>
)
React.render(element, container)
}
rerender("World")
第二步:创建dom节点函数
function createElement(type, props, ...children) {
//创建element
return {
type,
props: {
...props,
children: children.map(child =>
typeof child === "object"
? child
: createTextElement(child)
),
},
}
}
function createTextElement(text) {
//创建text类型
return {
type: "TEXT_ELEMENT",
props: {
nodeValue: text,
children: [],
},
}
}
function createDom(fiber) {
//创建dom
const dom =
fiber.type == "TEXT_ELEMENT"
? document.createTextNode("")
: document.createElement(fiber.type)
updateDom(dom, {
}, fiber.props)
return dom
}
第三步:更新节点函数
const isEvent = key => key.startsWith("on")
const isProperty = key =>
key !== "children" && !isEvent(key)
const isNew = (prev, next) => key =>
prev[key] !== next[key]
const isGone = (prev, next) => key => !(key in next)
function updateDom(dom, prevProps, nextProps) {
//更新节点属性
//删除老的事件
Object.keys(prevProps)
.filter(isEvent)
.filter(
key =>
!(key in nextProps) ||
isNew(prevProps, nextProps)(key)
)
.forEach(name => {
const eventType = name
.toLowerCase()
.substring(2)
dom.removeEventListener


533

被折叠的 条评论
为什么被折叠?



