React 中的 useTransition

在开发页面中,我们很常用的一种加载方式是使用 Suspense,在 fallback 属性设置一个加载标签,这样当我们需要远程加载数据时,可以显示 fallback 内容,当数据请求完成时,加载完整页面。但这种加载方式的一个缺点是在加载过程中阻碍了交互性,比如当用户在加载数据过程中,因等待时间较长,想要选择其他页面或者进行其他操作,就无法操作。这时候,我们可以使用 React 中的 useTransition。下面我们来介绍一下如何使用 useTransition

useTransition

useTransition 是一个 Hooks, 且不接受任何参数。

const [isPending, startTransition] = useTransition();

比如,在我们进行 Tab 内容切换时,我们可以对 Tab 组件的 onClick 事件进行 startTransition()

首先我们定一个页面,该页面右 Home,Contact,和 About 三个内容。当我们点击 Tab 的时候,自动对内容进行切换。该例子的灵感来源于 React 官网。

Page 页面内容:

import { useState, useTransition } from 'react';
import TabButton from './TabButton'
import AboutTab  from './AboutTab';
import HomeTab from './HomeTab';
import ContactTab from './ContactTab';

export default function Page() {
    const [tab, setTab] = useState('about');
    const [isPending, startTransition] = useTransition();

    function setTabContent(content) {
        startTransition(() => { // 使用 startTransition 使点击交互不阻塞
            setTab(content)
        })
    }

    return (
        <>
            <TabButton onClick={() => {
                setTabContent('about')
            }}
            >about</TabButton>
            <TabButton onClick={() => {
                setTabContent('contact')
            }}
            >contact</TabButton>
            <TabButton onClick={() => {
                setTabContent('home')
            }}
            >home</TabButton>

            {tab == 'about' && <AboutTab />}
            {tab == 'contact' && <ContactTab />}
            {tab == 'home' && <HomeTab />}
        </>
    )
}

TabButton 组件:

export default function TabButton({isActive, onClick, children}) {
    if(isActive) { // 区分是否 Active,如果 Active,则不需要为该 Tab 添加点击事件
        return(
            <b>{children</b>
        )
    }

    return(
        <button onClick={() => onClick()}>{children}</button>
    )
}

ContactTab 页面内容: 

import { memo } from 'react'

const ContactTab = memo(function() { // 使用 memo 从而 props 不变化时,组件不变
    let contacts = []
    for (let i = 0; i < 500; i++) {
        contacts.push(<SlowPost key={i} index={i} />);
    }

    return (
        <ul className="contacts">
            {contacts}
        </ul>
    )
})

function SlowPost({index}) {
    let startTime = performance.now()
    while(performance.now() - startTime < 1) { // 延迟模仿加载缓慢情况
    }

    return(
        <li className="item">
            Post {index + 1}
        </li>
    )
}

export default ContactTab;

About 和 Home 设置为静态页面,内容如下:

export default function HomeTab() {
    return (
        <p>home</p>
    )
}

这时候我们点击 TabButton,即使 Contact 页面内容加载延迟,但是点击 Tab 的事件依然可以响应,这是因为我们为点击事件包裹在  startTransiton() 方法里,该方法不返回任何值。

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值