当前位置:首页 > 科技  > 软件

React Suspense 进阶用法,结合 useTransition 使用

来源: 责编: 时间:2024-06-14 17:40:37 90观看
导读一、更舒适的交互先来看一下我们想要实现的交互效果,如图所示。我们在前面学习了 Suspense。Suspense 的 fallback 与子组件内容的显示是一个互斥关系。因此,当我们在请求过程中,需要显示 Loading 时,内容就会被隐藏掉。<

o8H28资讯网——每日最新资讯28at.com

一、更舒适的交互

先来看一下我们想要实现的交互效果,如图所示。o8H28资讯网——每日最新资讯28at.com

o8H28资讯网——每日最新资讯28at.com

我们在前面学习了 Suspense。Suspense 的 fallback 与子组件内容的显示是一个互斥关系。因此,当我们在请求过程中,需要显示 Loading 时,内容就会被隐藏掉。o8H28资讯网——每日最新资讯28at.com

<Suspense fallback={<Loading />}>  <Albums /></Suspense>

之前我们实现的交互效果如下。o8H28资讯网——每日最新资讯28at.com

o8H28资讯网——每日最新资讯28at.com

这种交互效果其实还可以,但是许多对交互有更高要求的团队,不会接受这样的页面大幅度抖动的交互。o8H28资讯网——每日最新资讯28at.com

例如在 antd 的 Table 组件中,它们选择的方案是在列表组件上覆盖了一个 Loading,此时的 Loading 效果与列表并非是一个互斥关系。这样的交互体验要比用 Loading 整体替换掉表格要好很多。o8H28资讯网——每日最新资讯28at.com

o8H28资讯网——每日最新资讯28at.com

所以,在目前学习阶段,我们面临的一个困惑就是,在使用 Suspense + use 来完成功能的同时,又如何优雅的做到这种非互斥的交互效果呢?o8H28资讯网——每日最新资讯28at.com

我们想要的最佳交互效果氛围两个阶段。o8H28资讯网——每日最新资讯28at.com

  •  初始化阶段,渲染 Suspense fallback 对应的组件。此时内部还没有办法显示,我们可以放置一个 Loading 或者骨架屏组件。
  • 更新阶段,我们希望阻止 fallback 的出现。直接在 Suspense 子组件内部处理更新阶段的 loading。这样就可以确保更新阶段,子组件内容与更新 loading 共存。

但是以目前学习到的知识点,肯定还做不到这样的效果,因此我们要引入新的概念:useTransition。o8H28资讯网——每日最新资讯28at.com

二、useTransition 概念解读

useTransition 是 React 专门为并发模式提供的一个基础 hook,它能够帮助我们在不阻塞 UI 渲染的情况下更新状态。意思就是说,我们可以借助 useTransition 将任务的优先级调得比 I/O 的响应低一些。o8H28资讯网——每日最新资讯28at.com

const [isPending, startTransition] = useTransition()

useTransition 的调用不需要参数,他的执行返回两个参数。o8H28资讯网——每日最新资讯28at.com

isPending:是否还存在等待处理的 transition,表示被降低优先级的更新任务还没有处理完成。o8H28资讯网——每日最新资讯28at.com

startTransition:标记任务的优先级为 transition,该优先级低于正常任务更新。它的用法如下,我们会将更新任务在它的回调函数中执行。o8H28资讯网——每日最新资讯28at.com

function TabContainer() {  const [isPending, startTransition] = useTransition();  const [tab, setTab] = useState('about');  function selectTab(nextTab) {    startTransition(() => {      setTab(nextTab);    });  }  // ……}

在优先级的排序中,被 startTransition 标记的任务比 Suspense fallback 更高一些。因此,我们可以利用这个特性,来避免 fallback 的渲染,当 startTransition 标记的任务执行完成,请求已经完成,此时 fallback 也就得不到渲染的机会了。o8H28资讯网——每日最新资讯28at.com

这里需要注意的是,标记的任务指的不是 setState ,而是对应的 UI 渲染任务,传递给 startTransition 的回调函数必须是同步函数。o8H28资讯网——每日最新资讯28at.com

我们可以正常这样使用。o8H28资讯网——每日最新资讯28at.com

startTransition(() => {  // ✅ 在调用 startTransition 中更新状态  setPage('/about');});

但是不能在回调函数中使用异步调用。这样会导致并发模式的任务排序出现问题。o8H28资讯网——每日最新资讯28at.com

startTransition(() => {  // ❌ 在调用 startTransition 后更新状态  setTimeout(() => {    setPage('/about');  }, 1000);});

但是,我们可以把 startTransition 传递给 setTimeout。o8H28资讯网——每日最新资讯28at.com

setTimeout(() => {  startTransition(() => {    // ✅ 在调用 startTransition 中更新状态    setPage('/about');  });}, 1000);
startTransition(async () => {  await someAsyncFunction();  // ❌ 在调用 startTransition 后更新状态  setPage('/about');});
await someAsyncFunction();startTransition(() => {  // ✅ 在调用 startTransition 中更新状态  setPage('/about');});

三、Suspense + useTransition

现在基于前面的知识点,我们来着手解决我们自己案例中的交互体验的提升。先来回顾一下之前的代码。o8H28资讯网——每日最新资讯28at.com

export default function Index() {  const [api, setApi] = useState(getApi)  function __clickToGetMessage() {    setApi(getApi())  }    return (    <div>      <div id='tips'>点击按钮获取一条新的数据</div>      <button onClick={__clickToGetMessage} disabled={isPending}>获取数据</button>      <div className="content">        <Suspense fallback={<div>loading...</div>}>          <Item api={api} isPending={isPending} />        </Suspense>      </div>    </div>  )}

在这个基础之上,我们只需要引入 useTransition 的使用即可。o8H28资讯网——每日最新资讯28at.com

export default function Index() {  const [api, setApi] = useState(getApi)  const [isPending, startTransition] = useTransition()  function __clickToGetMessage() {    startTransition(() => {      setApi(getApi())    })  }    ...}

setApi 所引发的任务更新被标记为 transition,他的优先级比 fallback 更高,因此此时我们需要等待 setApi 执行完成。isPending 表示是否还有待处理的 transition 任务,在这个案例中,他可以表示请求正在发生,作用与 loading 完全一致。o8H28资讯网——每日最新资讯28at.com

因此,我们可以将 isPending 传递给子组件,在子组件内部通过 isPending 来设计 loading UI。我们这里将组件的透明度调低。o8H28资讯网——每日最新资讯28at.com

<Item api={api} isPending={isPending} />
const Item = (props) => {  const {isPending, api} = props  const joke = use(api)  return (    <div       className='a_value'       style={{opacity: isPending ? 0.5 : 1}}    >{joke.value}</div>  )}

最终的演示效果如下:o8H28资讯网——每日最新资讯28at.com

o8H28资讯网——每日最新资讯28at.com

loading... 字样的出现表示初始化时请求接口。整体变浅表示更新时请求接口。完整的达到了我们的诉求。o8H28资讯网——每日最新资讯28at.com

四、input 中的实时请求

我们可以利用同样的方式,在搜索快速输入时做到这个交互。每一个字符的变化,在之前的尝试中,我们都会请求一次接口。因此之前的交互如下:o8H28资讯网——每日最新资讯28at.com

o8H28资讯网——每日最新资讯28at.com

我们希望如果列表已经显示过一次,那么在搜索过程中,列表就显示旧值,而不用切换到 fallback 的 Loading 组件。o8H28资讯网——每日最新资讯28at.com

o8H28资讯网——每日最新资讯28at.com

代码的调整与上面的案例几乎一样,如下:o8H28资讯网——每日最新资讯28at.com

export default function Index() {  const [api, setApi] = useState(postApi)  const [isPending, startTransition] = useTransition()  function __inputChange() {    startTransition(() => {      api.cancel()      setApi(postApi())    })  }  ....

但是,我们注意观察交互动画,当我们输入完之后,过了很长一段时间,isPending 状态才发生变化。也就是说,在这很长的时间里,一直有 transition 任务在执行。为什么会发生这种事情呢?然后我们观察了一下 network 面板,发现每一个请求都发生了。取消请求的代码并没有生效。o8H28资讯网——每日最新资讯28at.com

o8H28资讯网——每日最新资讯28at.com

当然,在官方文档中,也提到了,如果我们期望在交互过程中减少冗余请求的发生,我们可以继续使用防抖/节流来解决问题。o8H28资讯网——每日最新资讯28at.com

o8H28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-93868-0.htmlReact Suspense 进阶用法,结合 useTransition 使用

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 为什么要推荐使用现代化PHP框架?

下一篇: 抖音集团成 2024 年巴黎奥运会持权转播商

标签:
  • 热门焦点
  • 俄罗斯:将审查iPhone等外国公司设备 保数据安全

    俄罗斯:将审查iPhone等外国公司设备 保数据安全

    iPhone和特斯拉都属于在各自领域领头羊的品牌,推出的产品也也都是数一数二的,但对于一些国家而言,它们的产品可靠性和安全性还是在限制范围内。近日,俄罗斯联邦通信、信息技术
  • 28个SpringBoot项目中常用注解,日常开发、求职面试不再懵圈

    28个SpringBoot项目中常用注解,日常开发、求职面试不再懵圈

    前言在使用SpringBoot开发中或者在求职面试中都会使用到很多注解或者问到注解相关的知识。本文主要对一些常用的注解进行了总结,同时也会举出具体例子,供大家学习和参考。注解
  • .NET 程序的 GDI 句柄泄露的再反思

    .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 讲故事上个月我写过一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,当时用的是 GDIView + WinDbg 把问题搞定,前者用来定位泄露资源,后者用来定位泄露代码,后面有朋友反
  • 腾讯盖楼,字节拆墙

    腾讯盖楼,字节拆墙

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之&ldquo;想重温暴刷深渊、30+技能搭配暴搓到爽的游戏体验吗?一起上晶核,即刻暴打!&rdquo;曾凭借直播腾讯旗下代理格斗游戏《DNF》一
  • 网红炒股不为了赚钱,那就是耍流氓!

    网红炒股不为了赚钱,那就是耍流氓!

    来源:首席商业评论6月26日高调宣布入市,网络名嘴大v胡锡进居然进军了股市。在一次财经媒体峰会上,几个财经圈媒体大佬就&ldquo;胡锡进炒股是否知道认真报道&rdquo;展开讨论。有
  • iQOO 11S或7月上市:搭载“鸡血版”骁龙8Gen2 史上最强5G Soc

    iQOO 11S或7月上市:搭载“鸡血版”骁龙8Gen2 史上最强5G Soc

    去年底,iQOO推出了“电竞旗舰”iQOO 11系列,作为一款性能强机,iQOO 11不仅全球首发2K 144Hz E6全感屏,搭载了第二代骁龙8平台及144Hz电竞屏,同时在快充
  • 朋友圈可以修改可见范围了 苹果用户可率先体验

    朋友圈可以修改可见范围了 苹果用户可率先体验

    近日,iOS用户迎来微信8.0.27正式版更新,除了可更换二维码背景外,还新增了多项实用功能。在新版微信中,朋友圈终于可以修改可见范围,简单来说就是已发布的朋友圈
  • 联想的ThinkBook Plus下一版曝光,键盘旁边塞个平板

    联想的ThinkBook Plus下一版曝光,键盘旁边塞个平板

    ThinkBook Plus 是联想的一个特殊笔记本类别,它在封面放入了一块墨水屏,也给人留下了较为深刻的印象。据有人爆料,联想的下一款 ThinkBook Plus 可能更特殊,它
  • “买真退假” 这种“羊毛”不能薅

    “买真退假” 这种“羊毛”不能薅

    □ 法治日报 记者 王春   □ 本报通讯员 胡佳丽  2020年初,还在上大学的小东加入了一个大学生兼职QQ群。群主&ldquo;七王&rdquo;在群里介绍一些刷单赚
Top