洋洋得意入门
由于一开始两节课听得感觉很有趣,以为自己可以提前一步解决组件套用以及函数组件兼容,自己现在 createdElement 先加了两个判断
const createdElement = (type, props, ...children) => {
//判断是否是组件
if (typeof type === "object") {
return type;
}
//判断是不是函数组件
if (typeof type === "function") {
console.log("createdElementFFFFF", type, props, children);
const elm = {};
//记录函数组件 用于更新
functionComponents.push(elm);
Object.assign(elm, {
...type(props),
updateFunction: () => {
return type(props);
// Object.assign(elm, type(props));
},
});
return elm;
}
return {
type,
props: {
...props,
children: children.map((child) => {
return typeof child === "object" ? child : createTextElement(child);
}),
},
};
};
一开始 ,这个方法顺利解决了组件的渲染,洋洋得意的时候,接下来两节课我都没有发现啥不妥,还在纳闷为啥课程中为啥还需要在 commitWork判断fiber有没有dom,为啥我没有这一步也能实行渲染呢?难道我真的是天才?
逐渐感到不对劲
直到上到update 的课程,需要找到当前的fiber 进行函数组件的更新; 在这里我逐渐感到不对劲了,我发现我的方法在调用update时根本没办法找到wipFiber,但是这时候我又想到一个方法,让我的代码也能点击更新页面
就是在createElement 的时候将每个节点都push 到一个数组里面,当点击更新的时候,遍历所有保存的阶段,调用它的updateFunction 方法重新生成 新的节点
真的碰壁了
到了局部更新组件功能,我的办法彻底失效了,我对于 createdElement 中加入了函数组件的判断直接返回运算结果,其实无异议一开始就让函数组件变成普通的静态组件了,里面的变量 方法啥的都是执行时的状态,以至于update /useState 等都无法取的当前的fiber ,我试图将这个判断进行到底,也困扰了几天都一事无成......
浪子回头
最后我还是老老实实跟着课程的思路来实现min-react,学到最后理解了为什么 函数组件要放到
render 之后再处理,只有放这里才能生成新的fiber树 ,然后才能去比较更新...
最后优化课程代码,再加入了 函数组件使用map的判断 ,静态组件的判断
function createElement(type, props, ...children) {
// //判断children
if (Array.isArray(children[0])) {
//拍平
children = children.flat();
}
if (typeof type === "object") {
return type
}
return {
type,
props: {
...props,
children: children.map((child) => {
const isTextNode =
typeof child === "string" || typeof child === "number";
return isTextNode ? createTextNode(child) : child;
}),
},
};
}
实现了课程任务 TODOLIST
代码仓库: mini-react-study 完成todolist
学习心得
写代码,看清楚,思路清晰很重要,未看清楚瞎写容易事半功倍 你必须全力以赴,才能看起来毫不费力