当前位置:首页 > 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页面

创建 React 页面 使用 create-react-app 快速初始化项目: npx create-react-app my-app cd my-app npm start 编写组件代码 在 s…

如何优化react

如何优化react

优化 React 性能的方法 使用 React.memo 或 PureComponent 对于函数组件,使用 React.memo 进行记忆化,避免不必要的重新渲染。类组件可以使用 PureCompo…

react如何浮动

react如何浮动

使用 CSS 实现浮动 在 React 中实现浮动效果可以通过 CSS 的 float 属性完成。在组件的样式文件或内联样式中直接设置 float: left 或 float: right。 /…

react如何动画

react如何动画

React 动画实现方法 React 中实现动画可以通过多种方式,包括原生 CSS、第三方库或 React 内置的动画解决方案。以下是几种常见方法: 使用 CSS 动画和过渡 通过 CSS 的 tr…

react如何分

react如何分

React 分页实现方法 在 React 中实现分页功能可以通过多种方式完成,以下是几种常见的方法: 使用状态管理分页数据 在组件内部维护当前页码和每页数据量的状态,通过计算切片数据实现分页。…

如何搭建react项目

如何搭建react项目

使用 Create React App 搭建项目 Create React App (CRA) 是官方推荐的快速搭建 React 项目的工具,无需配置构建工具(如 Webpack 或 Babel)。…