首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

React Suspense没有按预期工作

React Suspense 是一个用于在 React 应用中处理异步加载组件的新特性。它允许你在组件等待某些数据或资源时“暂停”渲染,并显示一个备用 UI(如加载指示器)。以下是关于 React Suspense 的基础概念、优势、类型、应用场景以及可能遇到的问题和解决方案。

基础概念

React Suspense 允许你将组件的加载状态与渲染逻辑分离。它通常与 React.lazy 结合使用,后者允许你动态导入组件。

优势

  1. 更好的用户体验:通过显示加载状态,用户知道内容正在加载,而不是看起来像是卡住或出错。
  2. 代码分割:有助于减少初始加载时间,因为只有需要的组件才会被加载。
  3. 简化异步逻辑:将异步操作从组件内部移到外部,使组件代码更简洁。

类型

  • 数据获取:等待 API 响应。
  • 代码分割:动态导入组件。

应用场景

  • 懒加载组件:当页面包含多个组件且不是所有组件都需要立即加载时。
  • 数据密集型应用:在获取大量数据时显示加载状态。

可能遇到的问题及解决方案

问题1:Suspense 没有按预期显示加载状态

原因

  • 可能是因为组件没有正确地抛出 Promise
  • 或者是 React.lazy 导入的组件没有正确处理异步逻辑。

解决方案: 确保使用 React.lazy 正确导入组件,并且组件内部正确处理了异步逻辑。

代码语言:txt
复制
import React, { Suspense } from 'react';

const LazyComponent = React.lazy(() => import('./LazyComponent'));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <LazyComponent />
      </Suspense>
    </div>
  );
}

问题2:动态导入的组件加载失败

原因

  • 可能是由于网络问题或模块路径错误导致导入失败。

解决方案: 使用 Error Boundary 来捕获和处理加载错误。

代码语言:txt
复制
import React, { Suspense } from 'react';

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    console.error("Error loading component:", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <div>Something went wrong.</div>;
    }

    return this.props.children; 
  }
}

const LazyComponent = React.lazy(() => import('./LazyComponent'));

function App() {
  return (
    <div>
      <ErrorBoundary>
        <Suspense fallback={<div>Loading...</div>}>
          <LazyComponent />
        </Suspense>
      </ErrorBoundary>
    </div>
  );
}

示例代码

以下是一个完整的示例,展示了如何使用 React.lazySuspense 进行代码分割,并结合 ErrorBoundary 处理加载错误。

代码语言:txt
复制
import React, { Suspense } from 'react';

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    console.error("Error loading component:", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <div>Something went wrong.</div>;
    }

    return this.props.children; 
  }
}

const LazyComponent = React.lazy(() => import('./LazyComponent'));

function App() {
  return (
    <div>
      <ErrorBoundary>
        <Suspense fallback={<div>Loading...</div>}>
          <LazyComponent />
        </Suspense>
      </ErrorBoundary>
    </div>
  );
}

export default App;

通过这种方式,你可以确保即使在遇到问题时,用户也能得到清晰的反馈,而不是一个空白或不响应的页面。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

react-Suspense工作原理分析

Suspense 基本应用Suspense 目前在 react 中一般配合 lazy 使用,当有一些组件需要动态加载(例如各种插件)时可以利用 lazy 方法来完成。...要搞清楚这两个问题,首先要明白 Suspense 以及 lazy 是在整个过程中扮演的角色,这里先给出一个简单的结论:Suspense: 可以看做是 react 提供用了加载数据的一个标准,当加载到某个组件时...基本流程在深入了解细节之前,我们先了解一下 lazy + Suspense 的基本原理。这里需要一些 react 渲染流程的基本知识。...当 react 在 beginWork 的过程中遇到一个 Suspense 组件时,会首先将 primary 组件作为其子节点,根据 react 的遍历算法,下一个遍历的组件就是未加载完成的 primary...因此此时 primary 必定没有加载完成,所以也没必要再遍历一次。

78730
  • react-Suspense的工作原理解析

    Suspense 基本应用Suspense 目前在 react 中一般配合 lazy 使用,当有一些组件需要动态加载(例如各种插件)时可以利用 lazy 方法来完成。...要搞清楚这两个问题,首先要明白 Suspense 以及 lazy 是在整个过程中扮演的角色,这里先给出一个简单的结论:Suspense: 可以看做是 react 提供用了加载数据的一个标准,当加载到某个组件时...基本流程在深入了解细节之前,我们先了解一下 lazy + Suspense 的基本原理。这里需要一些 react 渲染流程的基本知识。...当 react 在 beginWork 的过程中遇到一个 Suspense 组件时,会首先将 primary 组件作为其子节点,根据 react 的遍历算法,下一个遍历的组件就是未加载完成的 primary...因此此时 primary 必定没有加载完成,所以也没必要再遍历一次。

    3.6K40

    React18 带来了什么

    当然,如果我们继续使用旧的 Render API,React 会按v17的方式去工作。以下是所有特性的一览表:图片为了更好地理解 React 18,我强烈建议你阅读官方给出的以下两篇 blog。...例如一个搜索按钮之后的视图变化,我们可以认为属于过渡视图,用户的预期中也是允许等待的,那我们就可以使用新的 API 来指定这些更新,让他们为更高的优先级的更新任务让步。...rfcs/0213-suspense-in-react-18.md at main · reactjs/rfcs它的原理是将子组件的渲染优先级降低,如果一个 Promise 还没有被 resolve,就会渲染...一个页面可能包含很多模块,某模块还没有被返回,页面中可以渲染 Suspense 提供的 fallback,已经加载过来的模块可以及时被 hydrate.2....但此时,如果用户点击了一下按钮,React 会把按钮的优先级提高,暂停另一个模块的 hydrate,优先对按钮模块进行 hydrate,以便于快速地响应用户的交互诉求。之后再接着之前没有完成的工作。

    75060

    在追寻极致体验的康庄大道上,React 玩出了花

    的详细信息,见React Suspense——从代码拆分加个 loading 说起…… Suspense 提供的优雅灵活、人性化的 loading 似乎已经达到极致的开发体验与用户体验了,然而,进一步探索发现...那么,有没有两全其美的办法,既能保证 loading 期间的响应性,又有类似于 loading 的交互体验呢? 有。...loading 非常快(只需要 100ms),用户可能只感觉到了什么东西忽闪而过……又一个糟糕的用户体验 当然,这样的场景我们通常不加 loading,因为 loading 通常带给用户一种“慢”的心理预期...如果愿意牺牲 UI 一致性的话 没有听错,UI 一致性也并非不可撼动,必要时可以考虑牺牲 UI 一致性来换取感知上更好的体验效果。...React 又考虑到了,所以提供了SuspenseList来控制 Suspense 内容的渲染顺序,保证列表中元素的显示顺序按相对位置来,避免内容被挤下去: coordinates

    1.6K20

    5 行代码理解 React Suspense

    已加载完的异步组件,安全 AnotherComponent Error Boundary 有个类似的东西是Error Boundary,也是 UI 层 try…catch 的一种,其安全的定义是组件代码执行没有...,具体见React Suspense | 具体实现 试玩一下: function App() { return ( Suspense fallback={loading......首次渲染结果符合预期,至于之后的更新过程(组件加载完成后把 loading 替换回实际内容),更多地属于 Lazy 组件渲染机制的范畴,与 Suspense 关系不大,这里不展开,感兴趣可参考React...}> Suspense> 前后几乎没有改动成本,甚至比调整 try…catch 边界还要容易(因为不用考虑变量作用域...四.在线 Demo 文中涉及的所以重要示例,都在 Demo 项目中(含详尽注释): react-suspense-and-try…catch 五.总结 Suspense 就像是 UI 层的 try…catch

    1.5K20

    React V16.9来了 无痛感升级 加入性能检测 【译-真香】

    但是,您可能没有时间迁移或测试这些组件。...这与React在处理真实浏览器事件时的工作方式相匹配,并有助于为将来React将更频繁地批量更新的组件做好准备。 但是,在16.8中act()仅支持同步功能。...2月份,我们发布了一个稳定的16.8版本,包括React Hooks,一个月后 React Native支持。但是,我们低估了此版本的后续工作,包括lint规则,开发人员工具,示例和更多文档。...现在React Hooks已经推出,并行模式和数据提取的悬念工作正在全面展开。目前正在积极开发的新Facebook网站建立在这些功能之上。...诚实的回答是,当我们开始时,它只需要比我们预期的更多的工作。与往常一样,我们感谢您在Twitter和我们的问题跟踪器中提出的问题和反馈。 安装 应对 Npm注册表中提供了React v16.9.0。

    4.8K30

    React 19 差点拖慢整个互联网!核心团队紧急叫停

    在 18 中执行的是“按组件”区分设计,也就是哪怕把两个组件放进同一个 Suspense 边界之内且各自执行获取,触发仍将并行执行:这会并行触发两条查询,等待两个查询解析后再显示整个子树。...一个更合适的描述应该是‘我们彻底改变了 React Suspense 在客户端组件中的工作方式’。Dominik 说道。...有使用了 React 19 的网友表示他在使用 RSC(React Server Components)时,这种方式仍然可以并行工作。...“迷途知返” “无论 Suspense 如何工作,提升数据要求都是一个好主意,我也建议这样做。然而,随着 React 19 的提议更改,这样做几乎成为强制性要求。”Dominik 说道。...这件事也引发了部分开发者对 React 长期以来没有与公众完全开放的沟通渠道的不满。

    48310

    被diss性能差,Dan连夜优化React新文档

    左Vue,右React Dan表示:当前文档还处于Beta版本,现在有更重要的工作要完成,正式版上线前会优化性能。...之前入口处全量引入了一个工具函数utils,现在将其中方法拆分成不同文件,这样能减少首屏bundle体积: 再比如: 这部分优化让bundle体积减少约一半: 其次,当前Next.js(文档使用的框架)没有默认开启...而React18的Selective Hydration为解决这一问题提供了好方法。 如果你的React18应用是SSR,那么被Suspense/>包裹的组件部分不会参与首次Hydrate的过程。...也就是说,被Suspense/>包裹的部分不会影响阻塞时间。 所以,虽然这部分工作很重要,但Dan需要做的,仅仅是把一些「对首屏显示不太重要的组件」包裹在Suspense/>中。...可以看到,在将一些组件用Suspense/>包裹前Hydrate作为一个长任务的耗时: 当包裹之后,这个长任务持续时间显著降低,进而降低TBT: 总结 这些只是初步的优化结果,后续还有很多优化工作值得去做

    89220

    React团队最近都在忙啥呢?

    不知道大家有没有一个感觉:React新特性的更新速度非常慢,时间通常是以年计。...实际上,在React漫长的发展过程中,除了很多优秀的特性(比如Hooks、Suspense)外,还有很多最终没有落地的想法。...这些想法通常不为开发者所知,这就带来一些「React新特性进展缓慢」的误解。 鉴于此,React官方博客[1]今天发布了一篇文章,介绍了团队当前工作的方向。...即使你还没完成年初的预期工作,也要相信挫折和颠覆是常态,而不是例外,无论好坏,即使在React团队也是如此。 不能因为你没有新的特性产出,就意味着你没有提供价值。...我想,这也是React团队公布接下来工作方向的一个原因吧。

    1.3K20

    React 18 RC 版本发布啦,生产环境用起来!

    还将之前 render 函数的回调函数干掉了,因为通常它在配合 Suspense 一起使用的时候得不到预期的效果: // 以前 const container = document.getElementById...为了完全支持服务端的 Suspense 和流式,改进了 react-dom/server 的 API,旧的 Node.js 流式 API 将会被完全弃用: renderToNodeStream 弃用⛔️️...另外,React 在这个版本还引入了新的 renderToReadableStream 来支持 Deno、Cloudflare worker 等其他环境的 和 Suspense。...想了解更多,可以看 React 18 官方工作组的博客:https://github.com/reactwg/react-18/discussions/22 批处理 React 中的批处理简单来说就是将多个状态更新合并为一次重新渲染...f); }); // 更新 DOM } 想了解更多可以看 React 18 官方工作组的博客:https://github.com/reactwg/react-18/discussions/21

    1.1K10

    如何升级到 React 18发布候选版

    这将创建一个在“遗留”模式下运行的 root,其工作原理与 React 17 完全相同。在发布之前,React 给这个 API 添加一个警告,指示它已被弃用,并切换到新的 Root API。...,因为通常在使用了 Suspense api 后没有达到预期的效果: // 以前 const container = document.getElementById('app') ReactDOM.render...为了完全支持服务端的 Suspense 和流式 SSR,改进了 react-dom/server 的 API,不支持 Suspense 的 Node.js 流式 API 将会被完全弃用: renderToNodeStream...在 React 18 之前,react 会将一个事件中的多个 setState 合并为一个,在 promises、 setTimeout、和其他异步事件的更新没有合并。...这个特性将使 React 具有更好的开箱即用性能,但是需要组件对多次挂载和销毁的效果具有弹性。大多数效果不需要任何改变就可以工作,但是有些效果假设它们只被安装或者销毁一次。

    2.3K20

    128. 精读《Hooks 取数 - swr 源码》

    本周精读就来剖析这个库的功能与源码,了解这个 React Hooks 的取数库的 Why How 与 What。 2 概述 首先介绍 swr 的功能。...2.7 乐观取数 特别在表单场景时,数据的改动是可预期的,此时数据驱动方案只能等待后端返回结果,其实可以优化为本地先修改数据,等后端结果返回后再刷新一次: import useSWR, { mutate...乐观取数,表示对取数结果是乐观的、可预期的,所以才能在结果返回之前就预测并修改了结果。...2.8 Suspense 模式 在 React Suspense 模式下,所有子模块都可以被懒加载,包括代码和请求都可以被等待,只要开启 suspense 属性即可: import { Suspense...uid=" + user.id); 怎么做到智能按依赖顺序请求呢?

    1.3K10

    React 并发 API 实战,这几个例子看懂你就明白了

    目录 什么是并发 它和 React 有什么关系 中断和切换是如何工作的 那 Suspense 呢?...中断和切换是如何工作的 在渲染低优先级更新时,React 在渲染完每个组件后会暂停,并检查是否有高优先级更新需要处理。如果有,React 会暂停当前渲染,切换到渲染高优先级更新。...那 Suspense 呢? 你可能听说过 CPU 密集型程序。这类程序大多数时间都在积极地使用 CPU 来完成它们的工作。...在 React 中负责处理 I/O 的组件是 Suspense。 如果组件在低优先级更新期间暂停,Suspense 的行为会有所不同。...需要注意的是,在 CPU 密集型组件的情况下,它们应该用React.memo包裹起来,否则即使它们的 props 没有变化,它们也会在每次高优先级渲染时重新渲染,这会影响你应用的性能。

    17310

    前端面试之React

    React没有这个,它是单向数据绑定的。React是一个单向数据流的库,状态驱动视图。...根据函数这种理念,React 的函数组件只应该做一件事情:返回组件的 HTML 代码,而没有其他的功能。函数的返回结果只依赖于它的参数。不改变函数体外部数据、函数执行过程里面没有副作用。...1.状态的有无 hooks出现之前,函数组件没有实例,没有生命周期,没有state,没有this,所以我们称函数组件为无状态组件。...hooks出现之前,react中的函数组件通常只考虑负责UI的渲染,没有自身的状态没有业务逻辑代码,是一个纯函数。它的输出只由参数props决定,不受其他任何因素影响。...这就要涉及到 Suspense 的工作原理,我们接着往下分析。

    2.6K20

    React Effects List大重构,是为了他?

    本文我们来看React内部Effects List机制重构的前因后果。 阅读完本文,你可以掌握React18对比之前版本,Suspense特性的差异及原因。...什么是副作用 简易的React工作原理可以概括为: 触发更新 render阶段:计算更新会造成的副作用 commit阶段:执行副作用 副作用包含很多类型,比如: Placement指DOM节点的插入与移动...新旧版React的差异 再回顾下开篇介绍的简易React工作原理: 触发更新 render阶段:协调器计算更新会造成的副作用 commit阶段:渲染器执行副作用 在开启并发之前,React保证一次...同时,为了在视觉上显得Sibling没有渲染,Sibling渲染的DOM节点会被设置display: none: 但这其实挺hack的。...你可以从这个在线Demo直观的感受新旧版Suspense的差异 总结 今天我们又学到了一个React源码小知识。

    43820

    React Effects List大重构,是为了他?

    本文我们来看React内部Effects List机制重构的前因后果。 阅读完本文,你可以掌握React18对比之前版本,Suspense特性的差异及原因。...什么是副作用 简易的React工作原理可以概括为: 触发更新 render阶段:计算更新会造成的副作用 commit阶段:执行副作用 副作用包含很多类型,比如: Placement指DOM节点的插入与移动...新旧版React的差异 再回顾下开篇介绍的简易React工作原理: 触发更新 render阶段:协调器计算更新会造成的副作用 commit阶段:渲染器执行副作用 在开启并发之前,React保证一次render...同时,为了在视觉上显得Sibling没有渲染,Sibling渲染的DOM节点会被设置display: none: 但这其实挺hack的。...值得一提的是,针对Suspense的这次改进,为React带来一种新的内部组件类型 —— Offscreen Component。 未来他可能是实现React版keep-alive的基础。

    65720
    领券