React 18 新特性(三):渐变更新

本文介绍了React 18的渐变更新特性,包括startTransition的使用,它允许将更新推迟以优先处理更重要的更新。通过一个搜索框的示例,展示了startTransition如何改善用户体验。同时,还讲解了useDeferredValue作为startTransition的语法糖,以及useTransition在异步加载和界面切换时如何避免闪烁问题,提供更好的过渡效果。
摘要由CSDN通过智能技术生成

前言

本文已收录在 Github: https://github.com/beichensky/Blog 中,欢迎 Star,欢迎 Follow!

React 18 新特性(一):自动批量更新 一文中提到:在 React 新版本中,更新会有优先级的顺序。

那如果希望更新时进行低优先级的处理,应该如何做呢,就是今天讲到的主题:渐变更新

如果还不知道如何搭建 React18 的体验环境,可以先查看这篇文章:使用 Vite 尝鲜 React 18

一、startTransition:渐变更新

  • startTransition 接受一个回调函数,可以将放入其中的 setState 更新推迟

  • 允许组件将速度较慢的更新延迟渲染,以便能够立即渲染更重要的更新

举个例子

先来看一个例子,在使用谷歌或者百度搜索时,都会遇到如下的场景:

a

这里的展示分为两部分

  • 一部分是输入框中的搜索内容

  • 另一部分是展示的联想内容。

从用户的角度进行分析:

  • 输入框中的内容是需要即时更新的

  • 而联想出来的内容是需要进行请求或者加载的,甚至于最开始的时候联想的不准确,用不到。所以用户可以接受这部分内容有一定延迟。

那在这种情况下,用户的输入就是高优先级操作,而联想区域的变化就属于低优先级的操作。

模拟代码实现这个例子

我们写一段代码来实现一下这个搜索框。

App.jsx

import React, { useEffect, useState, startTransition } from 'react';
import ReactDOM from 'react-dom';

const App = () => {
    const [value, setValue] = useState('');
    const [keywords, setKeywords] = useState([]);

    useEffect(() => {
        const getList = () => {
            const list = value
                ? Array.from({ length: 10000 }, (_, index) => ({
                      id: index,
                      keyword: `${value} -- ${index}`,
                  }))
                : [];
            return Promise.resolve(list);
        };
        getList().then(res => setKeywords(res));
    }, [value]);

    return (
        <>
            <input value={value} onChange={e => setValue(e.target.value)} />
            <ul>
                {keywords.map(({ id, keyword }) => (
                    <li key={id}>{keyword}</li>
                ))}
            </ul>
        </>
    );
};

// 使用 react 18 新的并发模式写法进行 dom render
ReactDOM.createRoot(document.getElementById('root')).render(<App />);

// legacy 旧模式
// ReactDOM.render(<App />, document.getElementById('root')!)

然后我们先看一下现在的效果(这里暂时不讨论防抖或者节流):

b

可以看到,不仅联想区域的内容加载缓慢,甚至用户的交互内容也反应迟钝。

既然刚才说到了低优先级更新,那么此时,我们是否可以让联想区域的内容低优更新,以避免抢占用户操作的更新呢?

接下来主角登场,使用 startTransition 对代码进行改造。

启用渐变更新

App.jsx

import React, { useEffect, useState, startTransition } from 'react';
import ReactDOM from 'react-dom';

const App = () => {
    const [value, setValue] =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值