Skip to content

Repository files navigation

从零实现 React

已实现

  • JSX 函数

  • Rollup 打包命令

  • 调试: 该方式不是热更新,有点繁琐 在 dist 的 react 目录下使用 pnpm link --global 将我们的 react 放入到全局的 node_modules 中 然后通过npx create-react-app react-demo创建一个项目 在 react-demo 目录下使用 pnpm link react --global 将 react 的指向改为我们写的 react 在 index.js 中打印, 然后通过npm start运行,打开控制台,就可以看到不同了

    import React from 'react';
    const jsx = (
    	<div>
    		hello <span>SuReact</span>
    	</div>
    );
    console.log(React);
    console.log(jsx);

    如下图: 可以看到我们打的标记 mark,同时发现 jsx 实现有点问题,span 没有显现,因为环境的原因

    image-20240402162003631

    只需更改 jsxDEV 即可,我们之前是一致的,同时将前面的 index.ts 导出的 createElement 换为 jsxDEV

    // jsxDEV 与 jsx 函数相比少了后面的...maybeChildren 参数
    export const jsxDEV = (type: ElementType, config: any) => {
    	let key: Key = null;
    	let ref: Ref = null;
    	const props: Props = {};
    
    	// 遍历配置对象,处理特殊属性(key 和 ref),将其余属性添加到 props 对象中
    	for (const prop in config) {
    		const val = config[prop];
    		if (prop === 'key') {
    			if (val !== undefined) {
    				key = '' + val; // 将 key 转换为字符串
    			}
    			continue;
    		}
    		if (prop === 'ref') {
    			if (val !== undefined) {
    				ref = val; // 设置 ref
    			}
    			continue;
    		}
    		// 调用空对象的hasOwnProperty方法, 确保只添加 config 对象自身的属性, 不添加原型链上的属性
    		if ({}.hasOwnProperty.call(config, prop)) {
    			props[prop] = val; // 将其余属性添加到 props 对象中
    		}
    	}
    	// 调用 ReactElement 函数创建并返回 JSX 元素
    	return ReactElement(type, key, ref, props);
    };

    再次查看,发现没问题了

    image-20240402163524432

  • FiberNode 节点, 工作循环 DFS

  • 接入更新机制, FiberRootNode 节点, 创建根容器和更新容器

  • mount 阶段

    • beginWork 函数, 负责在构建 Fiber 树时执行初始化工作,并开始处理工作单元

About

手写实现React

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages