Skip to content

Commit 3cb79f8

Browse files
author
wanglifa
committedMar 30, 2024
feat: 优化更新
1 parent 0f6400a commit 3cb79f8

File tree

2 files changed

+63
-50
lines changed

2 files changed

+63
-50
lines changed
 

‎vite-runner/App.jsx

+35-17
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,51 @@
11
import React from './core/React.js'
2-
let showBar = false
3-
function Counter() {
4-
const foo = (
2+
let countFoo = 1
3+
const Foo = () => {
4+
console.log('foo render')
5+
const update = React.update()
6+
const handleClick = () => {
7+
countFoo++
8+
update()
9+
}
10+
return (
511
<div>
6-
foo
7-
<div>child</div>
8-
<div>child2</div>
12+
<h1>foo</h1>
13+
{countFoo}
14+
<button onClick={handleClick}>click</button>
915
</div>
1016
)
11-
const bar = <p>bar</p>
12-
13-
function handleShowBar() {
14-
showBar = !showBar
15-
React.update()
17+
}
18+
let countBar = 1
19+
const Bar = () => {
20+
console.log('bar render')
21+
const update = React.update()
22+
const handleClick = () => {
23+
countBar++
24+
update()
1625
}
17-
1826
return (
1927
<div>
20-
Counter
21-
<button onClick={handleShowBar}>showBar</button>
22-
<div>{showBar ? bar : foo}</div>
28+
<h1>bar</h1>
29+
{countBar}
30+
<button onClick={handleClick}>click</button>
2331
</div>
2432
)
2533
}
34+
let countApp = 1
2635
function App() {
36+
console.log('app render')
37+
const update = React.update()
38+
const handleClick = () => {
39+
countApp++
40+
update()
41+
}
2742
return (
2843
<div>
29-
hi-mini-react
30-
<Counter></Counter>
44+
<h1>App</h1>
45+
{countApp}
46+
<button onClick={handleClick}>click</button>
47+
<Foo></Foo>
48+
<Bar></Bar>
3149
</div>
3250
)
3351
}

‎vite-runner/core/React.js

+28-33
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,29 @@ const createElement = (type, props, ...children) => {
1818
}
1919
}
2020
const render = (el, container) => {
21-
wipRoot = (nextWorkOfUnit = {
21+
wipRoot = {
2222
dom: container,
2323
props: {
2424
children: [el]
2525
}
26-
})
26+
}
27+
nextWorkOfUnit = wipRoot
2728
}
2829

2930
let wipRoot = null
3031
let currentRoot = null
3132
// 下一个任务(节点)
3233
let nextWorkOfUnit = null
3334
let deletions = []
35+
let wipFiber = null
3436
function workLoop(deadline) {
3537
let shouldYield = false
3638
while(!shouldYield && nextWorkOfUnit) {
3739
// 返回下一个节点
3840
nextWorkOfUnit = performWorkOfUnit(nextWorkOfUnit)
41+
if (wipRoot?.sibling?.type === nextWorkOfUnit?.type) {
42+
nextWorkOfUnit = null
43+
}
3944
// 这里为什么是小于 1
4045
shouldYield = deadline.timeRemaining() < 1
4146
}
@@ -72,7 +77,6 @@ const commitWork = (fiber) => {
7277
filberParent = filberParent.parent
7378
}
7479
if (fiber.effectTag === 'update') {
75-
console.log(3333)
7680
updateProps(fiber.dom, fiber.props, fiber.alternate?.props)
7781
} else if (fiber.effectTag === 'placement'){
7882
if (fiber.dom) {
@@ -87,18 +91,6 @@ const createDom = (type) => {
8791
return type === 'TEXT_ELEMENT' ? document.createTextNode('') : document.createElement(type)
8892
}
8993
const updateProps = (dom, nextProps, prevProps) => {
90-
console.log(nextProps, 'nnnnnnn')
91-
// Object.keys(props).forEach(attr => {
92-
// const isEvent = attr.startsWith('on')
93-
// if (isEvent) {
94-
// const eventType = attr.slice(2).toLocaleLowerCase()
95-
// dom.addEventListener(eventType, props[attr])
96-
// } else {
97-
// if (attr !== 'children') {
98-
// dom[attr] = props[attr]
99-
// }
100-
// }
101-
// })
10294
// 1. old 有 new 没有 -> 删除
10395
Object.keys(prevProps).forEach(key => {
10496
if (key !== 'children') {
@@ -110,10 +102,8 @@ const updateProps = (dom, nextProps, prevProps) => {
110102
// 2. old 没有 new 有 -> 添加
111103
// 3. new 有 old 也有 -> 修改
112104
Object.keys(nextProps).forEach(key => {
113-
console.log(1111111)
114105
if (key !== 'children') {
115106
if (nextProps[key] !== prevProps[key]) {
116-
console.log(nextProps[key], 'hhhhhhhh')
117107
// 不相等进行更新赋值
118108
const isEvent = key.startsWith('on')
119109
if (isEvent) {
@@ -149,14 +139,16 @@ const initChildren = (fiber, children) => {
149139
}
150140
} else {
151141
// 添加
152-
newFiber = {
153-
type: child.type,
154-
props: child.props,
155-
child: null, // child 和 sibling 初始化我们不知道
156-
sibling: null,
157-
parent: fiber,
158-
dom: null,
159-
effectTag: 'placement'
142+
if (child) {
143+
newFiber = {
144+
type: child.type,
145+
props: child.props,
146+
child: null, // child 和 sibling 初始化我们不知道
147+
sibling: null,
148+
parent: fiber,
149+
dom: null,
150+
effectTag: 'placement'
151+
}
160152
}
161153
if (oldFiber) {
162154
deletions.push(oldFiber)
@@ -174,14 +166,17 @@ const initChildren = (fiber, children) => {
174166
}
175167
// 考虑到我们还需要设置 parent.sibling,因为我们是从上往下获取的,所以work肯定是顶层也就是 parent,我们只能给 child 设置,
176168
// 但是如果直接在child 上加就会破坏原有结构,所以我们单独维护一个newWork 对象,
177-
prevChild = newFiber
169+
if (newFiber) {
170+
prevChild = newFiber
171+
}
178172
})
179173
while (oldFiber) {
180174
deletions.push(oldFiber)
181175
oldFiber = oldFiber.sibling
182176
}
183177
}
184178
const updateFunctionComponent = (fiber) => {
179+
wipFiber = fiber
185180
const children = [fiber.type(fiber.props)]
186181
initChildren(fiber, children)
187182
}
@@ -190,7 +185,6 @@ const updateHostComponent = (fiber) => {
190185
// 1. 创建dom
191186
const dom =(fiber.dom = createDom(fiber.type))
192187
// 3. 设置 dom 的 props
193-
console.log(fiber, 'xxxxxxxxx')
194188
updateProps(dom, fiber.props, {})
195189
}
196190
const children = fiber.props.children
@@ -218,14 +212,15 @@ const performWorkOfUnit = (fiber) => {
218212
}
219213
requestIdleCallback(workLoop)
220214

221-
// 这里的节点不是新的节点吗,那么新节点的 alternate 指向旧节点为啥也是 currentRoot 难道currentRoot 即是新节点也是旧节点?
222215
const update = () => {
223-
nextWorkOfUnit = {
224-
dom: currentRoot.dom,
225-
props: currentRoot.props,
226-
alternate: currentRoot
216+
let currentFiber = wipFiber
217+
return () => {
218+
wipRoot = {
219+
...currentFiber,
220+
alternate: currentFiber
221+
}
222+
nextWorkOfUnit = wipRoot
227223
}
228-
wipRoot = nextWorkOfUnit
229224
}
230225
const React = {
231226
render,

0 commit comments

Comments
 (0)
Please sign in to comment.