本次课程我们来处理一个edge case. 代码如下,现在运行会报错。
import React from './core/React.js';
let showBar = false
function Counter({ num }) {
const bar = <div>bar</div>
function handleShowBar() {
showBar = !showBar
React.update()
}
return <div>
Counter
<button onClick={handleShowBar}>showBar</button>
{showBar && bar}
</div>
}
function App() {
return <div>
hi-mini-react
<Counter></Counter>
</div>
}
export default App;
尝试定位问题
function createElement(type, props, ...children) {
return {
type,
props: {
...props,
children: children.map(child => {
console.log('child 111', child)
const isTextNode = typeof child === "string" || typeof child === "number"
return isTextNode ? createTextNode(child) : child
})
}
}
}
- 打印一下child,出现false,找到了问题点,false不是textNode也不是对象节点
- 额外处理,false的情况,reconcileChildren增加
if (child) {
function reconcileChildren(fiber, children) {
let oldFiber = fiber.alternate?.child
let prevChild = null
children.forEach((child, index) => {
const isSameType = oldFiber && oldFiber.type === child.type
let newFiber
if (isSameType) {
//update
newFiber = {
type: child.type,
props: child.props,
child: null,
parent: fiber,
sibling: null,
dom: oldFiber.dom,
effectTag: "update",
alternate: oldFiber
}
} else {
if (child) {
newFiber = {
type: child.type,
props: child.props,
child: null,
parent: fiber,
sibling: null,
dom: null,
effectTag: "placement"
}
}
if (oldFiber) {
deletions.push(oldFiber)
}
}
if (oldFiber) {
oldFiber = oldFiber.sibling
}
if (index === 0) {
fiber.child = newFiber
} else {
prevChild.sibling = newFiber
}
prevChild = newFiber
})
while (oldFiber) {
deletions.push(oldFiber)
oldFiber = oldFiber.sibling
}
}
- 可以正常切换
新的问题,修改app中的位置
return <div>
Counter
{showBar && bar}
<button onClick={handleShowBar}>showBar</button>
</div>
- 报错了
- 处理button的时候拿之前的节点拿不到
- 赋值增加判断
function reconcileChildren(fiber, children) {
if (newFiber) {
prevChild = newFiber
}
})