当前位置:首页 > React

如何手写一个react

2026-03-30 14:43:19React

手写一个简易 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];
}

完整示例

将以上部分组合成一个可运行的示例:

如何手写一个react

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 通过闭包和链表结构管理组件状态。

标签: react
分享给朋友:

相关文章

react如何创建项目

react如何创建项目

使用 Create React App 创建项目 Create React App (CRA) 是官方推荐的 React 项目脚手架工具,适合快速初始化一个现代化的 React 项目。 安装 C…

如何编译react文件

如何编译react文件

编译 React 文件的方法 使用 Create React App (CRA) Create React App 是官方推荐的快速搭建 React 项目的工具,内置了 Babel 和 Webpack…

react如何修改值

react如何修改值

修改 React 组件的值 在 React 中修改值通常涉及状态管理。根据组件的类型(类组件或函数组件)和状态管理方式(本地状态或全局状态),方法有所不同。 使用 useState(函数组件) 在函…

react如何传递参数

react如何传递参数

传递 props 给子组件 在父组件中通过属性名直接传递数据,子组件通过 props 对象接收。例如父组件传递 name 和 age: <ChildComponent name="John"…

react 如何渲染的

react 如何渲染的

React 渲染机制 React 的渲染过程分为两个主要阶段:协调(Reconciliation)和提交(Commit)。协调阶段负责计算差异(Diffing),提交阶段将变化应用到 DOM。 虚拟…

如何搭建react框架

如何搭建react框架

安装 Node.js 和 npm 确保系统已安装 Node.js(包含 npm)。可通过官网下载安装包或使用版本管理工具(如 nvm)。安装完成后,运行以下命令验证版本: node -v npm…