React16源码: Suspense与lazy源码实现

React 之 Suspense 进行异步网络请求,然后再拿到请求后的数据进行渲染是很常见的需求,但这不可避免的需要先渲染一次没有数据的页面,数据返回后再去重新渲染。组件来渲染子组件,这个组件的特性是能根据传入 mode 来控制子组件样式的显隐,这有一个好处,就是能保存组件的状态,有些许类似于 Vue 的。至此,Suspense 的一生我们粗略的过完了,在源码中对 Suspense 的处理非常多,涉及到优先级相关的本篇都略过。通过其需要的 mode 参数值,我们可以大胆的猜测,应该是一个能控制是否显示子组件的组件,如果。 阅读详情

Suspense 与 lazy


1 )概述

  • Suspense 是在 react16.6 提供的新 feature
  • 用于加载的缓冲的内置组件

2 )示例程序

lazy.js

// lazy.js
import React from 'react'
export default () => <p>Lazy Comp</p>

主程序

import React, { Suspense, lazy } from 'react'

const LazyComp = lazy(() => import('./lazy.js'))

let data = ''
let promise = ''
function requestData() {
  if (data) return data
  if (promise) throw promise
  promise = new Promise(resolve => {
    setTimeout(() => {
      data = 'Data resolved'
      resolve()
    }, 2000)
  })
  throw promise
}

function SuspenseComp() {
  const data = requestData()
  return <p>{data}</p>
}

export default () => (
  <Suspense fallback="loading data">
    <SuspenseComp />
    <LazyComp />
  </Suspense>
)
  • 示例的效果是先显示的是 loading data,然后再显示出来 Data resolved
  • 最终 export出去的这个组件,它是一个 function component
    • 里面使用了 Suspense,然后给它一个 fallback 的 prop
    • 这就是我们看到的 loading data,里面是一个组件(SuspenseComp),也是一个function component
    • 调用了一个 requestData 方法,它渲染的是一个p标签, 填充 data
  • 可以在一个 Suspense 组件,下面渲染一个或者多个这种异步的组件
    • 有任何一个抛出了 promise以及在这个 promise relove 之前
    • 都会显示这个 fallback里的内容
  • 这就是 Suspense 组件的一个原理
    • 其实它具体的内部实现是非常复杂的
  • 注意,16.6版本的React只支持lazy就是异步加载组件
    • 并没有很好的去支持我们的异步数据加载的功能
    • 相关源码没有稳定,跟数据加载相关的是 Suspense 的功能后期发布
    • 在后面的版本进行使用,当前版本是不推荐在生产环境使用
  • Suspense支持 lazy组件,可以非常方便的实现异步组件加载
    • 配合webpack提供的 import 来实现这个功能
    • 比如代码中, const LazyComp = lazy(() => import('./lazy.js'))
    • 这个 LazyComp 也被放到这个 Suspense 里面
  • 在控制台的 network 面板里面,刷新一下
    • 可以看到bundle.js 然后 2.chunk.js
    • 这就是我们进行了一个异步加载组件,自动给我们区分的一个 js 文件
  • 因为其实我们是在本地开发的,异步加载速度非常快
    • 最终 LazyComp 跟 Data resolved 是一起显示出来的
    • 如果在 Suspense 组件内部有多个组件,要等到所有的组件都resolved之后
    • 它才会把fallback里面的内容移除,这是 Suspense 的一个特点
    • 如果里面任何一个组件处于 pending 状态,它还是会显示 fallback

3 ) 源码探究

  • 定位到 React.js, 找到 Suspense

     import {
       REACT_SUSPENSE_TYPE,
     } from 'shared/ReactSymbols';
     import { lazy } from './ReactLazy';
    
     const React = {
       // ... 此处省略其他
       lazy,
       // ... 此处省略其他
       Suspense: REACT_SUSPENSE_TYPE
     }
    
    • 看到 Suspense它是一个常量,就是一个 REACT_SUSPENSE_TYPE,本质上只是一个Symbol
    • 而 lazy 就不是一个Symbol 了
    • 我们可以看到 import { lazy } from './ReactLazy';
  • 基于这个,定位到 ReactLazy.js 查看 lazy 源码

    /**
     * Copyright (c) Facebook, Inc. and its affiliates.
     *
     * This source code is licensed under the MIT license found in the
     * LICENSE file in the root directory of this source tree.
     */
    
    import type {LazyComponent, Thenable} from 'shared/ReactLazyComponent';
    
    import {REACT_LAZY_TYPE} from 'shared/ReactSymbols';
    
    export function lazy<T, R>(ctor: () => Thenable<T, R>): LazyComponent<T> {
      return {
        $$typeof: REACT_LAZY_TYPE,
        _ctor: ctor,
        // React uses these fields to store the result.
        _status: -1,
        _result: null,
      };
    }
    
  • 它是一个方法 export function lazy,并接收一个方法

    • lazy<T, R>(ctor: () => Thenable<T, R>): LazyComponent<T>
    • 它指定这个传入的参数,这个参数是一个方法,并且它要返回一个 Thenable 类型的对象
    • Thenable 是 Promise 这样的一个对象,它具有 .then 方法
  • 最终,返回的是一个 lazy component

    • $$typeof,值为 REACT_LAZY_TYPE
    • _ctor 就是我们传递进来的回调函数
      • 在react渲染的过程当中,渲染到 lazy component 的时候
      • 会去调用这个 _ctor 回调,并返回一个 Thenable 的对象(Promise对象)
      • 这个时候Promise是处于 pending 状态的,对应的是值是 -1
    • _status 用来记录当前这个 Thenable 的对象,所处的状态
      • 后续达到了resolved 或者是 rejected 的这两种状态的时候,这个 _status 会变化
      • 让后期进行渲染的时候可以进行不一样的处理
    • _resultPromise结果
      • 用来记录这个Thenable对象,它 resolve 之后返回的那个属性
      • 在 lazy 里面,最终的组件会挂载到这个 _result
      • 后续渲染这个 lazy 组件的时候,直接拿 _result 里面的组件渲染就可以了
2024高项范文-论项目成本管理 例如,在需求分析和设计阶段,安排了较多经验丰富的人员,确保基础工作的高质量完成,同时也避免了后续因需求变更等问题导致的时间和成本浪费。虽然项目进度略有延迟,但通过有效的成本管理和调整,最终在可控的成本范围内完成了项目,并且软件的质量也得到了保障。通过这个案例可以看出,在项目成本管理过程中,要紧密结合时间管理,根据实际情况灵活调整策略,注重风险的防范和应对,才能实现时间和成本的平衡,确保项目的成功。资源规划是成本基准形成的基础。识别和评估项目中的成本风险,并制定相应的应对措施,以降低风险对项目成本的影响。 阅读详情

相关推荐

Star CCM+中衍生零部件下的阈值应用与区域内删除目标网格

同样的在绘制网格结束后,有时出现负体积网格或质量差的网格,为了节约时间成本,可能会选择将负体积的网格或质量差的网格删除。弹出相应的窗口,在窗口中选择相应的区域①,选择标量函数②(此处以网格体积变化为例),选择模型③,设置阈值④,选择No Dispalyer,会根据需求选择显示,最后点击Create⑥完成创建。此处以温度为例,若出现温度异常点,首先在①栏中勾选Function,然后在下面点击⑤Select,在弹出的Function窗口中选择温度场函数,再点击④Identify,查找温度异常网格数量。

2201_75375391的博客 2223

react-Suspense工作原理分析

之所以是将 Suspense 放在最后来分析,是因为对 Suspense 的处理涉及到多个状态,这些状态在之前的步骤中或许会被修改,因此在了解其他步骤之后再来看 Suspense 或许更容易理解。从上面的描述即可以看出,Suspense 是一个加载数据的标准,lazy 只是该标准下实现的一个工具方法。beginWork - second pass,由于此时 DidCapture 存在,会将 primary 组件作为子节点,并将 fallback 组件作为 primary 组件的兄弟节点。

grooyo的博客 962

STM32 HAL库 实现基于SPI模式的SD卡、TF卡FATS文件系统+模拟U盘的应用笔记

很多单片机不带SDIO接口,所以在使用SD卡时必须使用SPI模式进行读写。 想做一个基于SPI的SD卡文件系统读写SD卡上的文件,再配合USB接口做一个模拟U盘。只能利用业余时间慢慢更新,也不知道能不能坚持下去。 我会把从零开始开发一个程序需要经历的过程一一的记录下来。做成一个奶妈级的单片机开发笔记。 一、硬件简介 1.SD卡和MicroSD卡(TF卡)的区别 由下图可以很容易的看出TF卡只是比SD卡少了一个3脚Vss脚,其它的管脚顺序

KyleKuang的博客 8336

React16源码: React中详解在渲染阶段Suspend的源码实现

1 )把优先级放到低优先级的任务上会把当前 render 直接废弃,让低优先级的任务再次去渲染这些更新来查看他是否可以把错误解决掉2 )直接发起一个新的同步更新没有低优先级的任务,会重新发起的是同步更新来强制再次去渲染一次来看是否可以解决这个问题如果不能解决,那么就代表不能解决这个问题,只能按照错误的方式去把内容渲染出来3 )设置timeout然后提交只有在 throw 的是 Promise 的情况。

Wang的专栏 1358

面板数据分析中的随机前沿软件FRONTIER Version 4.1应用

随机前沿模型是一种用于评估单位效率的统计方法。它考虑了输入和输出的随机性,允许我们在效率评估中引入不确定性。随机前沿模型通常用于评估生产单位、金融机构、医院等各种类型的决策单元的效率。FRONTIER是一个广泛使用的随机前沿分析软件,具有用户友好的界面和强大的功能。它提供了估计效率、前沿分析和模型比较的工具,使用户能够深入研究单位的效率和绩效。面板数据是一种包含多个单位(通常是时间序列数据)的数据类型,可以用于分析单位在不同时间点的变化和效率。

目标检测专栏持续更新中,改进YOLO系列通用,适用v5、v7、v8、所有博客均是团队原创博客,所有文章禁止转载,违者必究。 2983

基于Kubernetes的ML平台架构设计

本文在Kubernetes开源组件的基础上,对ML平台各部分组件的作用进行了介绍,并且进行了组件选型,初步设计了ML平台的技术架构。

2401_83124266的博客 2052

Suspense

这个是为了 懒加载 React Suspense让我们轻松定义延迟加载的组件。 为什么会出现这种情况呢? ---》 因为在路由中使用的懒加载路由方式 所以说 难免会有点慢 如果没有这个处理 那么就会出现一段时间的白屏 用户体验较差 const OtherComponent = React.lazy(() => import('./OtherComponent')); function MyComponent() { return ( <div> <Su

大路宽宽的博客 589

MOOS-ivp 实验三 MOOS简介(1)

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录系列文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例

weixin_44151170的博客 7434

深度理解 React Suspense

本文介绍与 Suspense 在三种情景下使用方法,并结合源码进行相应解析。欢迎关注个人博客。 Code Spliting 在 16.6 版本之前,code-spliting 通常是由第三方库来完成的,比如 react-loadble(核心思路为: 高阶组件 + webpack dynamic import), 在 16.6 版本中提供了 Suspense 和 lazy 这两个钩子, 因此在之后...

weixin_33868027的博客 442

fdtd(时域有限差分)仿真

基础入门阶段采用 Step by step 的教学方式带着做具体的案例,在案例中学习 FDTD 应用的。的痛难点,将 FDTD 仿真引入实验当中,通过软件可视化处理有效直观的展示仿真的流程,与实验数。图像传感器,OLED 和液晶,表面计量,表面等离子体,石墨烯,太阳能电池,集成光子组件,超材。料,衍射光学和光子晶体。波,场极化,磁场,周期性结构,半球功率积分等设计解决方案,提供时域有限差分分析函数,时域。子光学传感器、热电子光探测器的光学特性研究、光学微腔宽带吸收器等多个方向的研究方法。

y2715163545的博客 5454

具身智能:从理论突破到场景落地的全解析

具身智能(Embodied Intelligence)是人工智能与机器人学深度融合的前沿领域,其核心在于通过物理实体与环境的动态交互实现智能行为。区别于传统 AI 的 “离身性”(如语音助手仅依赖数据输入),具身智能强调 “智能体通过身体感知世界并反作用于环境”,形成 “感知 - 决策 - 行动” 的闭环。例如,能自主避障的配送机器人、可精准抓取异形物体的机械臂,均通过传感器网络与环境实时互动,在试错中优化行为策略。

LeeKumaの技术Note 2683

【React源码26】深入学习React 源码实现——React.lazy 与 Suspense 的底层实现

本文深入解析了React.lazy与Suspense的源码实现,从历史背景到核心原理全面剖析。主要内容包括:1)React v16.6引入原生懒加载的动机;2)React.lazy的数据结构设计及其状态管理机制;3)resolveLazyComponent函数如何通过Promise实现异步加载;4)Fiber架构下beginWork阶段对LazyComponent的特殊处理流程。通过源码分析揭示了React如何将动态导入与渲染系统深度集成,实现了高效组件加载机制。

silverclayz的技术分享 1164

用Python爬虫抓取大宗交易成交数据:全面解析与实战代码

大宗交易是指在证券市场中,涉及大额买卖的交易。此类交易通常由机构投资者进行,其交易量较大,对市场的影响显著。大宗交易数据包含了买卖双方的成交价格、成交量等关键信息,这些数据对于投资者和分析师而言,具有重要的市场预测意义。Python爬虫是一种自动化抓取互联网上数据的工具。通过爬虫,我们可以定期获取大宗交易数据,节省人工查询的时间。爬虫的工作原理通常包括:发送HTTP请求、获取响应数据、解析网页内容、提取关键信息、存储和展示数据。

2201_76125261的博客 417

深入理解 React Lazy Loading:用 React.lazy 与 Suspense 构建高性能 React 应用

本文是一份关于 React 懒加载(Lazy Loading)的完整实战指南,源自 refine(一个用于构建内部工具、后台管理面板与 B2B 应用的 React 框架)官方博客的工程主题文章。全文将系统讲解懒加载的核心原理、`React.lazy` 与动态 `import()` 的使用方式、`Suspense` 回退 UI、错误边界(ErrorBoundary)、路由级与组件级代码分割,并延伸到

gitblog_01095的博客 901

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

react.lazy 路由懒加载_React lazy/Suspense使用及源码解析

React v16.6.0已经发布快一年了,为保障项目迭代发布,没有及时更新react版本,最近由于开启了新项目,于是使用新的react版本进行了项目开发。项目工程如何搭建,如何满足兼容性要求,如何规范化等等这里不作为介绍重点,这里想说一下react的lazy,suspense,这块在react官网作为code-splitting重点说明过,可见其出现的意义。官网写的比较详细,总结起来就是,如果你...

weixin_39800387的博客 1187

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

深入理解React:懒加载(lazy)实现原理

目录 代码分割 React的懒加载 import() 原理 React.lazy 原理 Suspense 原理 参考 1.代码分割 (1)为什么要进行代码分割? 现在前端项目基本都采用打包技术,比如 Webpack,JS逻辑代码打包后会产生一个 bundle.js 文件,而随着我们引用的第三方库越来越多或业务逻辑代码越来越复杂,相应打包好的 bundle.js 文件体积就会越来越大,因为需要先请求加载资源之后,才会渲染页面,这就会严重影响到页面的首屏加载。 而为了解决这样的问题,避

大灰狼的小绵羊哥哥的博客 7167

suspense源码分析

Suspense 的核心概念与 error boundaries 非常相似,error boundaries 在 React 16 中引入,允许在应用程序内的任何位置捕获未捕获的异常,然后在组件树中展示跟错误信息相关的组件。以同样的方式,Suspense 组件从其子节点捕获任何抛出的Promises,不同之处在于对于 Suspense 我们不必使自定义组件充当边界,Suspense 组件就是那个边界;而在 error boundary中,我们需要为边界组件定义(componentDidCatch)方法。-.

susuzhe 770

react 日历组件_anujs1.5.1支持React.Suspense与lazy

React16是一个实验版本,除了测试它的新fiber架构外,还添加了大量新功能。其他React.Suspense与React.lazy就是重磅中的重磅。随着前端的APP化,不断集成功能,页面越来越大,bundle size以MB为单位,我们需要拆分代码,实现动态化加载非首屏功能。比日历,城市选择器,评论组件等等。动态加载,在javascript模块加载规范中已经有草案,并且被webpack, r...

weixin_39614637的博客 119

深度理解 React Suspense(附源码解析)

本文介绍与 Suspense 在三种情景下使用方法,并结合源码进行相应解析。欢迎关注个人博客。 Code Spliting 在 16.6 版本之前,code-spliting 通常是由第三方库来完成的,比如 react-loadble(核心思路为: 高阶组件 + webpack dynamic import), 在 16.6 版本中提供...

weixin_34250434的博客 302

react lazy + Suspense / loadable 实现路由懒加载

目录 前言 为什么要代码分割? 第三方库方案——react-loadble “lazy 方法 +Suspense 组件”方案 前言 在 16.6 版本之前,代码分割通常是由第三方库来完成的,比如 react-loadble(核心思路为: 高阶组件 + webpack dynamic import)。在 16.6 版本中提供了 Suspense 和 lazy 这两个方法来实现代码分割。 为什么要代码分割? React 项目打包时,如果不进行异步组件的处理,那么所有页面所需要的 js 都..

青蛙king的博客 761

React 源码解析之总览

本小书大部分内容来自作者 Jokcy 的 《React 源码解析》: react.jokcy.me/ 本文已同步在我的博客: ruizhengyun.cn/blog/post/2… 感谢 Jokcy 让我深度了解 React。如他所说,在决定阅读 React 源码时认为不会是一件很难的事,但是真正开始阅读之后才发现,事情没那么简单,因为需要足够的耐心、能够独立思考和静下心来(因为你会碰到之前编码...

weixin_34008933的博客 216

React 16.6的懒加载组件

React 16.6 添加了一个使代码拆分更容易的新功能:React.lazy()。 我们通过一个小演示看看如何以及为什么要使用此功能。我们有一个显示股票列表的应用程序,当单击一只股票时,它会显示一个图表: 可以去github下载源码GitHub - pomber/react-lazy-preload-demo: Lazy loading (and preloading) components in React16.6Lazy loading (and preloading) components..

qq_45679015的博客 1016

React 现代化改造实战指南:版本升级、Class 迁移 Hooks 与 React 18 并发特性

本篇技术指南以 agents24/agents 仓库中 `framework-migration` 插件所附带的 `react-modernization` 技能为骨架,系统讲解 React 应用的现代化改造路径:从 React 16→17→18 的版本升级与破坏性变更应对,到 Class 组件向 Hooks 的迁移、并发特性(Suspense、Transitions)的落地,以及 jscodes

gitblog_00152的博客 389

react-loadable vs React.lazy:React代码分割方案选型终极对比指南

先说结论:如果你在做**纯客户端的 React 单页应用**,用内置的 `React.lazy` + `Suspense` 就够了;如果你需要**服务端渲染(SSR)、预加载、精细控制加载体验**,那么经典方案 [react-loadable](https://link.gitcode.com/i/d35317f41ffa459dfe3554d854b6683d) 依然是更强大的选择。react-

gitblog_01185的博客 226

Relay 的 useLazyLoadQuery 完全指南:渲染期惰性查询、Fetch Policy 与 Suspense 实践

`useLazyLoadQuery` 是 React Relay 提供的 React Hook,用于在组件渲染期间获取并读取一条 GraphQL 查询的数据。本指南以 Relay v16 官方 API 文档为核心,结合仓库源码([useLazyLoadQuery.js](https://link.gitcode.com/i/6e9d8e6727305af338b00c66af845e65)、[Qu

gitblog_00561的博客 571
上一篇: React16源码: ConcurrentMode的使用及源码实现
下一篇: React16源码: Hooks源码实现
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值