import React from './core/React.js'
function Counter() {
return <div>count</div>
}
const App = <div>
hi-mini-react
<Counter></Counter>
</div>
export default App
我们直接运行会报错
在 createDom 里打印我们的 type 发现是一个函数
ƒ Counter() {
return /* @__PURE__ */ React.createElement("div", null, "count");
} 'yyyyy'
所以通过 document.createElement(type) 会报错
在 preformWorkOfUnit 里判断如果是function 类型的话我们就不创建dom
const isFunctionComonent = typeof fiber.type === 'function'
if (!isFunctionComonent) {
if (!fiber.dom) {
// 1. 创建dom
const dom =(fiber.dom = createDom(fiber.type))
// 3. 设置 dom 的 props
updateProps(dom, fiber.props)
}
}
接着设置我们的 children,想拿到 counter 的children 也就是他下面的div需要调用这个函数也就是 fiber.type(),因为他返回的是一个对象所以我们需要对 children 特殊处理
const initChildren = (fiber, children) => {
let prevChild = null
children.forEach((child, index) => {})
}
// performWorkOfUnit
const children = isFunctionComonent ? [fiber.type()] : fiber.props.children
initChildren(fiber, children)
运行代码报错
因为我们的div的父元素 counter 没有dom,所以我们需要继续找 父元素的父元素直到找到就将它添加到下面
const commitWork = (fiber) => {
+ let filberParent = fiber.parent
+ if (!filberParent.dom) {
+ filberParent = filberParent.parent
+ }
+ filberParent.dom.append(fiber.dom)
commitWork(fiber.child)
commitWork(fiber.sibling)
}
这时候页面里会出现一个null
因为我们的 counter 本身没有dom,所以我们要判断dom存在才添加
嵌套的 function component
function Counter() {
return <div>count</div>
}
function CounterContainer () {
return <Counter></Counter>
}
const App = <div>
hi-mini-react
<CounterContainer></CounterContainer>
</div>
报错还是之前的原因因为我们又多了一个没有dom的父节点,而我们之前的代码只会找父级的父级,而这次是cc依然没有dom,所以我们需要循环直到找到一个有dom的节点
while (!filberParent.dom) {
filberParent = filberParent.parent
}
支持 props
function Counter({num}) {
return <div>count: {num}</div>
}
function CounterContainer () {
return <Counter num={1}></Counter>
}
const performWorkOfUnit = (fiber) => {
...
const children = isFunctionComonent ? [fiber.type(fiber.props)] : fiber.props.children
...
}
报错,因为我们的 num 最后要渲染为 textNode,而我们只处理了string
const createElement = (type, props, ...children) => {
return {
type,
props: {
...props,
+ children: children.map(child => ['string', 'number'].includes(typeof child) ? createTextNode(child) : child)
}
}
}
支持多个组件传 props
import React from './core/React.js'
function Counter({num}) {
return <div>count: {num}</div>
}
const App = <div>
hi-mini-react
<Counter num={10}></Counter>
<Counter num={20}></Counter>
</div>
export default App
页面只会展示一个
正常我们从 count:10 应该走到 counter,但是代码逻辑里,它没有兄弟就会找父级的兄弟,它的父级是div,div也没有兄弟,所以如果当前节点没有兄弟节点就找它父级的兄弟节点,如果父级也没有兄弟节点,就找父级的父级
let nextFilber = fiber
while(nextFilber) {
if (nextFilber.sibling) {
return nextFilber.sibling
}
nextFilber = nextFilber.parent
}