React Fiber 树思想解决业务实际场景详解

 更新时间:2022年12月19日 11:01:16   作者:明里人  
这篇文章主要为大家介绍了React Fiber 树思想解决业务实际场景详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

熟悉 Fiber 树结构

我们知道,React 从 V16 版本开始采用 Fiber 树架构来实现渲染和更新机制。

Fiber 在 React 源码中可以看作是一个任务执行单元,每个 React Element 都会有一个与之对应的 Fiber 节点。

Fiber 节点的核心数据结构如下:

type Fiber = {
  type: any, //类型  
  return: Fiber, //父节点
  child: Fiber, // 指向第一个子节点
  sibling: Fiber, // 指向下一个弟弟
}

其中,以下三个属性可以构成 Fiber 树:

  • return 表示父 Fiber 节点(顶级元素没有 return 指针)
  • sibling 表示下一个兄弟 Fiber 节点(如果没有下一个兄弟节点,也就没有这个指针)
  • child 表示第一个子 Fiber 节点(如果没有第一个子节点,也就没有这个指针)。

举个例子,假如我们的组件结构如下:

function App() {
  return (
    <div>
      名称:
      <span>明里人</span>
    </div>
  )
}

对应的 Fiber 树结构如下:

通过 Fiber 树结构我们可以很方便的查找一个节点的上级、下级和同级。

接下来我们一起来看看实际的业务场景。

业务场景

有时我们会去实现一些任务类的需求,任务自身存在 status 状态,比如进行中、逾期、完成状态,每个任务都可以通过完成按钮被完成。

假设现在有一个「任务流」作为第一级数据出现,它的子集由一个或多个「任务组」组成,作为第二级数据出现,任务组的子集由一个或多个「任务」组成,作为第三级数据出现。

现有需求如下:

第三级的「任务」在完成时更新自身状态,但要考虑同步上级节点的状态:

  • 如果当前任务所在的任务组下所有任务都已完成,更新当前「任务组」状态为完成;
  • 如果所有任务组及任务都已完成,更新「任务流」状态为完成。

当「任务流」处于完成状态时,UI 的体现可能如下:

思路:

我们要在每个任务完成后,判断同级任务是否都已完成,若都已完成,则将父级(任务组)状态更新为完成。

如果我们将现有的菜单树结构改造为 Fiber 树结构,通过 return 可以很方便的找到父节点,然后通过 child 和 sibling 可以很方便的查找任务组下的每一个任务,决定是否更新任务组状态。

代码实现如下:

// 1. taskFlowData 任务流数据
// 2. currentTaskData 当前完成的任务数据
export const getFinishedStatus = (task) => task.status === 1; // 1 代表完成
export const setFinishedStatus = (task) => task.status = 1;
// 首先,将当前任务的状态更新
setFinishedStatus(currentTaskData);
// 第一步,将现有数据转换为 Fiber 树结构
const createNode = (value, parent) => (
  { value, return: parent, child: null, sibling: null }
);
// 1-1. 创建 root fiber 根节点,即 任务流
const rootNode = createNode(taskFlowData, undefined);
let currentNode = rootNode, currentTaskNode = null;
// 1-2. child 存放的是任务组,为第二级数据创建 Fiber 节点
currentNode.value.child.forEach((taskGroup, taskGroupIndex) => {
  const node = createNode(taskGroup, rootNode);
  // 1-3. 建立关系
  taskGroupIndex === 0 ? (currentNode.child = node) : (currentNode.sibling = node);
  // 1-4. 为第三级任务创建 Fiber 节点
  taskGroup.child.forEach((task, taskIndex) => {
    const childNode = createNode(task, node);
    taskIndex === 0 ? (node.child = childNode) : (currentNode.sibling = childNode);
    currentNode = childNode;
    // 1-5. 记录当前任务对应的 Fiber 节点
    if (task.id === currentTaskData.id) currentTaskNode = currentNode;
  });
  currentNode = node;
});
// 第二步,根据 Fiber 树结构,来查找并更新状态
let parentNode = currentTaskNode.return;
while (parentNode) {
  let isFinished = true;
  // 2-1. 找到第一个任务
  let workInprgress = parentNode.child;
  // 2-2. 从第一个任务开始,依次查看每个任务的状态
  while (workInprgress) {
    // 2-3. 如果查找的当前任务处于未完成状态,无需更新父级状态
    if (!getFinishedStatus(workInprgress.value)) {
      isFinished = false;
      break;
    }
    workInprgress = workInprgress.sibling;
  }
  // 2-4. 更新任务组状态,再向上查找,确定是否更新任务流状态
  if (isFinished) {
    setFinishedStatus(parentNode.value);
    parentNode = parentNode.return;
  } else {
    // 2-5. 任务组状态不需要更新,直接结束
    break;
  }
}

以上就是React Fiber 树思想解决业务实际场景详解的详细内容,更多关于React Fiber树业务场景的资料请关注脚本之家其它相关文章!

相关文章

  • react native图片解析流程详解

    react native图片解析流程详解

    这篇文章主要为大家介绍了react native图片解析流程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • 教你如何实现在react项目中嵌入Blazor

    教你如何实现在react项目中嵌入Blazor

    这篇文章主要介绍了如何实现在react现有项目中嵌入Blazor,通过这个案例我们可以知道 blazor也可以像react那样嵌入在任何的现有项目中,并且使用方便,需要的朋友可以参考下
    2023-01-01
  • React中Key属性作用

    React中Key属性作用

    react中的key属性,它是一个特殊的属性,它是出现不是给开发者用的,而是给React自己使用,有了key属性后,就可以与组件建立了一种对应关系,本文主要介绍了React中Key属性作用,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • 浅谈react前后端同构渲染

    浅谈react前后端同构渲染

    本篇文章主要介绍了浅谈react前后端同构渲染,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • React 中使用 react-i18next 国际化的过程(react-i18next 的基本用法)

    React 中使用 react-i18next 国际化的过程(react-i18next 的基本用法)

    i18next 是一款强大的国际化框架,react-i18next 是基于 i18next 适用于 React 的框架,本文介绍了 react-i18next 的基本用法,如果更特殊的需求,文章开头的官方地址可以找到答案
    2023-01-01
  • react-player实现视频播放与自定义进度条效果

    react-player实现视频播放与自定义进度条效果

    本篇文章通过完整的代码给大家介绍了react-player实现视频播放与自定义进度条效果,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2022-01-01
  • React中阻止事件冒泡的问题详析

    React中阻止事件冒泡的问题详析

    这篇文章主要给大家介绍了关于React中阻止事件冒泡问题的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用React具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • React组件间通信的三种方法(简单易用)

    React组件间通信的三种方法(简单易用)

    React知识中一个主要内容便是组件之间的通信,以下列举几种常用的组件通信方式,本文就详细的介绍一下,感兴趣的可以了解一下
    2021-10-10
  • ReactQuery系列React Query 实践示例详解

    ReactQuery系列React Query 实践示例详解

    这篇文章主要为大家介绍了ReactQuery系列React Query 实践示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • react native 文字轮播的实现示例

    react native 文字轮播的实现示例

    这篇文章主要介绍了react native 文字轮播的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07

最新评论