JSX如何转成react-fiber的?

什么是fiber?

一个fiber本质上是一个Fiber类的实例,以下是实例中的各个属性。可以看出,每一个Fiber节点之间通过指针相互关联,并找到下一个Fiber节点。因此,所有的Fiber节点相互关联就形成了Fiber树。

kotlin 复制代码
// 静态 Instance

this.tag = tag  //组件类型
this.key = key 
this.elementType = null  //和type大部分时间相同,除非使用react.memo包裹函数
this.type = null //和elementType大部分时间相同
this.stateNode = null  // 对应真实dom节点

// Fiber  //链表关系
this.return=null // 关联父节点
this.child=null // 关联子节点
this.sibling=null // 关联兄弟节点
this.index=0 // 同级fiber节点,代表它们插入dom的索引

this.ref = null // 字面意思,就是ref

/*------------------------作为动态单元的属性---------------------------*/

this.pendingProps = pendingProps
this.memoizedProps = null
this.updateQueue = null
this.memoizeState = null
this.dependencies = null

this.mode = mode

// Effects // 名称中带有effect的和副作用相关,
this.effectTag = NoEffect
this.subtreeTag = NoSubtreeEffect
this.deletions = null
this.nextEffect = null

this.firstEffect = null
this.lastEffect = null

this.lanes = NoLanes // 和优先级调度有关
this.childLanes = NoLanes

this.alternate = null // 与fiber架构的双缓存机制有关

Fiber节点是如何产生的呢?

Fiber树的产生源自于JSX模板,如以下代码:

假设我们有一个简单的 React 函数组件 ExampleComponent

javascript 复制代码
function ExampleComponent() {
  return (
    <div className="container">
      <h1>Hello, World!</h1>
      <p>This is an example component.</p>
    </div>
  );
}

首先,webpack编译时,Babel将其转化为普通的JS代码,在这里,React.createElement的三个参数:元素类型、属性对象和子元素。

jsx 复制代码
function ExampleComponent() {
  return React.createElement(
    'div',
    { className: 'container' },
    React.createElement('h1', null, 'Hello, World!'),
    React.createElement('p', null, 'This is an example component.')
  );
}

React.createElement做了什么事情呢?

React.createElement() 是 React 中用于创建虚拟 DOM 元素的函数。它接收三个参数:类型、属性对象和子元素,然后返回一个描述该元素的 JavaScript 对象

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: []
    }
  };
}

上述代码是一个简化版的示例,实际的 React.createElement() 实现还包含其他功能,例如处理 keyref 等特殊属性,以及一些性能优化。以下是编译后的产物,可以认为是vNode

json 复制代码
{
  "type": "div",
  "props": {
    "className": "container",
    "children": [{
      "type": "h1",
      "props": {
        "children": [{
          "type": "TEXT_ELEMENT",
          "props": {
            "nodeValue": "Hello, World!",
            "children": []
          }
        }]
      }
    }, {
      "type": "p",
      "props": {
        "children": [{
          "type": "TEXT_ELEMENT",
          "props": {
            "nodeValue": "This is an example component.",
            "children": []
          }
        }]
      }
    }]
  }
}

vNode 转化为 Fiber 结构:

javascript 复制代码
// 定义 Fiber 对象
class Fiber {
  constructor(vNode) {
    this.type = vNode.type;
    this.props = vNode.props;
    this.key = vNode.key;
    this.child = null;
    this.sibling = null;
    this.alternate = null;
    // 其他需要用到的属性和状态
  }
}

// 构建 Fiber 树
function createFiberTree(vNode) {
  const fiber = new Fiber(vNode);

  if (vNode.children) {
    let prevChildFiber = null;
    vNode.children.forEach(childVNode => {
      const childFiber = createFiberTree(childVNode);
      if (prevChildFiber === null) {
        fiber.child = childFiber;
      } else {
        prevChildFiber.sibling = childFiber;
      }
      prevChildFiber = childFiber;
    });
  }

  return fiber;
}


// 将 vNode 转化为 Fiber 结构
const fiberTree = createFiberTree(vNode);

createFiberTree 函数用于递归构建 Fiber 树,根据 vNode 的层次结构创建相应的 Fiber 对象,并将子节点和兄弟节点连接起来。 生成的Fiber节点如下

javascript 复制代码
const exampleFiber = {
  type: "div",
  props: {
    className: "container",
  },
  child: Fiber { 
      type: 'h1', 
      props: { children: "Hello, World!" },
      key: null, 
      child: null, 
      sibling: Fiber { ... }, 
      alternate: null, 
  },
  sibling: null,
  return: null
};

exampleFiber.child = {
  type: "h1",
  props: { children: "Hello, World!" },
  child: null,
  sibling: null,
  return: exampleFiber
};

exampleFiber.child.sibling = {
  type: "p",
  props: { children: "This is an example component." },
  child: null,
  sibling: null,
  return: exampleFiber
};

在上述代码中,我们创建了两个子节点的 Fiber 对象,并将它们连接到父节点 exampleFiberchildsibling 属性上。通过这种方式,我们可以构建出一个简单的 Fiber 树结构。

在这里能得到的一个信息是,每一个元素都会变成一个Fiber节点。当后续这些元素关联的变量发生改变时,它又是怎样去触发更新的呢?

相关推荐
LaughingZhu18 小时前
智能体经典范式构建:ReAct、Plan-and-Solve 与 Reflection
前端·react.js·前端框架
飞天狗19 小时前
长列表滚动卡顿怎么破:虚拟列表选型 + react-virtuoso 实战调优指南
react.js·性能优化
binbin_521 天前
React 井字棋教程:用一个小游戏理解组件和状态
前端·react.js·前端框架
张元清1 天前
React useObjectUrl Hook:预览文件与 Blob,不留内存泄漏(2026)
javascript·react.js
真的想不出名儿1 天前
Md编辑器整合-react
前端·react.js·编辑器
牛仔只喝牛奶2 天前
多端跨端技术选型:小程序 + H5 + App 的两栈拆分落地
react native·react.js
wear工程师2 天前
setState 到底是不是异步的?这题从 React 16 问到 18,标准答案早就变了
react.js·面试
wanghowie2 天前
LangGraph4j 落地(二)— ReAct 多步工具与 trace 扩展
前端·react.js·前端框架
csj502 天前
前端基础之《React(11)—state声明式》
前端·react.js
张元清2 天前
React useLocalStorage Hook:SSR 安全的持久化状态(2026)
javascript·react.js