如何手写一个react
手写一个简易 React 的实现
创建一个简易 React 需要实现核心功能:虚拟 DOM、组件渲染和状态管理。以下是关键步骤和代码示例。
实现虚拟 DOM 和渲染
虚拟 DOM 是一个 JavaScript 对象,描述真实 DOM 的结构。使用 createElement 函数生成虚拟 DOM 节点:
function createElement(type, props, ...children) {
return {
type,
props: {
...props,
children: children.map(child =>
typeof child === "object" ? child : createTextElement(child)
),
},
};
}
function createTextElement(text) {
return {
type: "TEXT_ELEMENT",
props: {
nodeValue: text,
children: [],
},
};
}
实现渲染函数
render 函数将虚拟 DOM 转换为真实 DOM 并挂载到容器中:
function render(element, container) {
const dom =
element.type === "TEXT_ELEMENT"
? document.createTextNode("")
: document.createElement(element.type);
const isProperty = key => key !== "children";
Object.keys(element.props)
.filter(isProperty)
.forEach(name => {
dom[name] = element.props[name];
});
element.props.children.forEach(child =>
render(child, dom)
);
container.appendChild(dom);
}
实现 Fiber 架构
Fiber 是 React 的协调算法,用于增量渲染。以下是简化版的 Fiber 实现:
let nextUnitOfWork = null;
function workLoop(deadline) {
let shouldYield = false;
while (nextUnitOfWork && !shouldYield) {
nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
shouldYield = deadline.timeRemaining() < 1;
}
requestIdleCallback(workLoop);
}
requestIdleCallback(workLoop);
function performUnitOfWork(fiber) {
if (!fiber.dom) {
fiber.dom = createDom(fiber);
}
if (fiber.parent) {
fiber.parent.dom.appendChild(fiber.dom);
}
const elements = fiber.props.children;
let index = 0;
let prevSibling = null;
while (index < elements.length) {
const element = elements[index];
const newFiber = {
type: element.type,
props: element.props,
parent: fiber,
dom: null,
};
if (index === 0) {
fiber.child = newFiber;
} else {
prevSibling.sibling = newFiber;
}
prevSibling = newFiber;
index++;
}
if (fiber.child) {
return fiber.child;
}
let nextFiber = fiber;
while (nextFiber) {
if (nextFiber.sibling) {
return nextFiber.sibling;
}
nextFiber = nextFiber.parent;
}
}
实现函数组件和 Hooks
支持函数组件和 useState Hook:
function useState(initial) {
const [oldHook] = fiber.hooks || [];
const hook = {
state: oldHook ? oldHook.state : initial,
queue: [],
};
const actions = oldHook ? oldHook.queue : [];
actions.forEach(action => {
hook.state = action(hook.state);
});
const setState = action => {
hook.queue.push(action);
nextUnitOfWork = {
dom: currentRoot.dom,
props: currentRoot.props,
alternate: currentRoot,
};
};
fiber.hooks.push(hook);
return [hook.state, setState];
}
完整示例
将以上部分组合成一个可运行的示例:

const Didact = {
createElement,
render,
useState,
};
function Counter() {
const [state, setState] = Didact.useState(1);
return Didact.createElement(
"button",
{ onClick: () => setState(c => c + 1) },
"Count: ",
state
);
}
const element = Didact.createElement(Counter, null);
const container = document.getElementById("root");
Didact.render(element, container);
关键点总结
- 虚拟 DOM 是轻量级的 JavaScript 对象,描述 UI 结构。
render函数递归地将虚拟 DOM 转换为真实 DOM。- Fiber 架构实现增量渲染,避免阻塞主线程。
useState通过闭包和链表结构管理组件状态。






