(一)手写 React 源码之准备阶段

学习点

相关的基本概念如:虚拟 DOM、JSX 等

代码仓库:github.com/kjhuanhao/j...

React 是什么

需求:在页面上显示一个按钮,按钮显示的文字内容为:Hello, Count:0,每点击一次该按钮,count 的数字加1

JS实现

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #content {
      font-size: 22px;
      border: 1px solid grey;
      cursor: pointer;
      padding: 6px 10px;
      display: inline-block;
      border-radius: 10px;
    }
  </style>
</head>
<body>
  <div id="root">
    <div id="content" onclick="changeText()">Click Me, Count: 0</div>
  </div>
  <script lang="javascript">
    let count = 0;
    function changeText() {
      count++;
      document.getElementById("content").innerHTML = `Click Me, Count: ${count}`;
    }
  </script>
</body>
</html>

React实现

javascript 复制代码
import { useState } from 'react';

export default function MyApp() {
  return (
    <div>
      <h1>Counters that update separately</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}

初始准备

初始化一个 React 项目

初始化之后删除掉无用的代码和文件,以便我们可以更好去学习

  • index.js
javascript 复制代码
import ReactDOM from 'react-dom/client';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<div>Simple React</div>);
  • index.html
javascript 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Simple React</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

虚拟 DOM

DOM 是 html 的编程接口,通过 DOM 的方式可以操作文档的结构、样式和内容

  1. DOM 是针对 html、xml 编程接口和编程语言无关
  2. DOM 实现相当于一个独立的程序,可以用 js、java、python 实现
  3. 而通过DOM 实现可以获取一个 DOM 对象,从而操作 DOM 对象
javascript 复制代码
let element = document.getElementById('root')
let obj = {}
for (let key in element){ obj[key] = element[key]}
console.log(obj) 

可以通过代码去修改 DOM 对象,但是开销会非常大,所以引入了虚拟 DOM,虚拟 DOM 是用于描述 DOM对象的对象,在 js 中绝大部分的 DOM 对象的都是非必需的

在 react 中直接打印一个react 对象

javascript 复制代码
console.log(<div>Simple React</div>)

总之,对比来看

  1. 没有虚拟 DOM 的情况下,直接操作一个 DOM 对象,其发生的变化需要遍历整棵 DOM 树
  2. 有虚拟 DOM 的情况下,直接操作一个 DOM 对象就是操作其虚拟 DOM,根据前后两个虚拟 DOM 之间的变化,可以计算出页面需要变化的地方

JSX 相关概念

JSX 是 JavaScript 的语法扩展,他既不是 js 也不是 html,通常我们使用 babel 来进行 jsx 的转换

JSX 相关概念

JSX 是 JavaScript 的语法扩展

  • 新的转换形式
javascript 复制代码
import ReactDOM from 'react-dom/client';

const root = ReactDOM.createRoot(document.getElementById('root'));
let element = <div>Hello</div>
root.render(element);

编译后会变成这样的 js 代码,为什么刚刚在 babel 中会有所不同

javascript 复制代码
let element = /*#__PURE__*/(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("div", {
  children: "Hello"
}, void 0, false, {
  fileName: _jsxFileName,
  lineNumber: 4,
  columnNumber: 15
}, undefined);

babel编译后的,实际上是因为开发环境和生产环境的不同导致的

javascript 复制代码
import { jsx as _jsx } from "react/jsx-runtime";
const element = /*#__PURE__*/_jsx("div", {
  children: "123"
});

不管是哪种方式,它们返回的都是一个虚拟 DOM 对象

  • 旧的转换形式,需要导入 React
javascript 复制代码
import React from 'react';
let element = <div>Hello</div>
React.createElement("div", null, "Hello")

React 和 ReactDOM 的职责划分

  • react:组件相关核心 API 的暴露
  • react-dom:和 react 配套,将写好的组件进行渲染
相关推荐
牛仔只喝牛奶12 小时前
多端跨端技术选型:小程序 + H5 + App 的两栈拆分落地
react native·react.js
wear工程师16 小时前
setState 到底是不是异步的?这题从 React 16 问到 18,标准答案早就变了
react.js·面试
wanghowie18 小时前
LangGraph4j 落地(二)— ReAct 多步工具与 trace 扩展
前端·react.js·前端框架
csj5019 小时前
前端基础之《React(11)—state声明式》
前端·react.js
张元清20 小时前
React useLocalStorage Hook:SSR 安全的持久化状态(2026)
javascript·react.js
析数塔20 小时前
2026前端框架深度解析:React Compiler、Angular Zoneless、Vue 3.5重写游戏规则
前端·vue.js·react.js
杖雍皓20 小时前
没有服务器如何构建现代 Web 应用:平台选型与组合策略
运维·服务器·前端·react.js·github·netlify·vercel
sun_weitao20 小时前
微前端框架之qiankun 怎么用?vue3+vite+qiankun 和 react + qiankun
前端·react.js·前端框架
名字还没想好☜2 天前
React useEffect 依赖数组踩坑:闭包陷阱与清理函数
前端·javascript·react.js·react·useeffect
我是大卫2 天前
【图】React源码解析-第四部分:事件与跨层传递
react.js·源码