如何手写一个react
手写一个简单的 React
创建一个基础的 React 实现需要理解其核心概念:虚拟 DOM、组件、状态管理和渲染。以下是一个简化版的 React 实现。
创建虚拟 DOM
虚拟 DOM 是真实 DOM 的轻量级表示,通常是一个 JavaScript 对象。
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: [],
},
};
}
渲染函数
渲染函数将虚拟 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);
}
组件系统
创建一个简单的组件系统,支持函数组件。
function createRoot(container) {
return {
render(element) {
render(element, container);
},
};
}
function useState(initialState) {
let state = initialState;
const setState = newState => {
state = newState;
// 触发重新渲染
render();
};
return [state, setState];
}
示例使用
将上述代码组合起来,创建一个简单的计数器应用。
function Counter() {
const [count, setCount] = useState(0);
return createElement(
"div",
null,
createElement("h1", null, "Count: ", count),
createElement(
"button",
{ onClick: () => setCount(count + 1) },
"Increment"
)
);
}
const root = createRoot(document.getElementById("root"));
root.render(createElement(Counter, null));
优化与扩展
为了更接近真实的 React,可以添加以下功能:
- Diffing 算法:比较新旧虚拟 DOM,只更新变化的部分。
- Fiber 架构:支持异步渲染和任务分片。
- Hooks 系统:扩展 useState 以支持更多钩子。
- 事件系统:标准化事件处理。
完整代码示例
// 完整代码将上述部分组合起来
// 注意:这是一个简化版,真实 React 更复杂
通过以上步骤,可以构建一个基础的 React 实现。真实场景中,React 还包含更多优化和功能,但核心概念是相似的。







