0

0

浅析react18中的新概念Transition

青灯夜游

青灯夜游

发布时间:2022-03-25 10:52:46

|

2884人浏览过

|

来源于掘金社区

转载

本篇文章带大家了解一下react18的新概念transition,简单介绍一下新api:starttransition和新hooks:usetransition和usedeferredvalue的使用方法,希望对大家有所帮助!

浅析react18中的新概念Transition

React 18中,引入了一个新概念——transition,由此带来了一个新的API——startTransition和两个新的hooks——useTransitionusedeferredValue,本文由此展开使用尝鲜介绍。【相关推荐:Redis视频教程

1. 总览

本文分为4部分进行:

  • tansition 产生初衷
  • startTransition 使用和介绍
  • useTransition 使用和介绍
  • useDeferredValue 使用和介绍

2. transition产生初衷

transtion 直接翻译为 过渡。tansition本质上是为了解决渲染并发问题所提出。在React中一旦组件状态改变并触发了重新渲染,则无法停止渲染。直到组件重新渲染完毕,页面才能继续响应用户的交互。

为此react 18中更新都可以划分为以下两类:

  • 紧急更新(urgent update):用户期望马上响应的更新操作,例如鼠标单击或键盘输入。
  • 过渡更新(transition update):一些延迟可以接受的更新操作,如查询时,搜索推荐、搜索结果的展示等。
// 被startTransiton标记后为过渡更新
startTransition(()=> {
    // 非紧急更新,会被降低优先级,延迟执行
    setQueryValue(inputValue)
})

// 未被标记则马上执行
setInputValue(inputValue)

在react 18中被startTrionstion标记的更新,即为过渡更新(执行的优先级被降低),此时react会根据内部的调度机制延迟执行内部的state更新。

开发中开发者可以通过transition hook决定哪些更新被标记为transition事件。一旦被标记则代表为低优先级执行,即react知道该state可以延迟更新,通过区分更新优先级,让高优先级的事件保持响应,提高用户交互体验,保持页面响应

3. startTransiton

startTransiton使用介绍

const handleClick = () => {
    // startTransition包裹标记为低优先级更新
    startTransition(()=> {
        setQueryValue(inputValue)
    })
    
    // 未被标记则马上执行
    setInputValue(inputValue)
}

首先我们来介绍下最简单的startTransition

  • startTransiton 是一个接受回调的函数,用于告知React需要延迟更新的state。
  • 如果某个state的更新会导致组件挂起,则应该包裹在startTransition中

通过演示对比

这是一个对输入字符后展示搜索结果的场景模拟,通过伪造大量搜索结果,模拟容易卡顿的情况。

我们试着连续输入123,监听搜索框值value变化(urgent update)和搜索值searchVal变化(transition update)并输出到控制栏。

import React, { useEffect, useState, startTransition } from 'react';
import './App.css'

const SearchResult = (props) => {
    const resultList = props.query
        ? Array.from({ length: 10000 }, (_, index) => ({
            id: index,
            keyword: `${props.query} -- 搜索结果${index}`,
        })) : [];
    return resultList.map(({ id, keyword }) => (
        
  • {keyword}
  • )) } const App = () => { const [type, setTpye] = useState(1) const [value, setValue] = useState(''); const [searchVal, setSearchVal] = useState('-'); useEffect(() => { // 监听搜索值改变 console.log('对搜索值更新的响应++++++' + searchVal + '+++++++++++') }, [searchVal]) useEffect(() => { console.log('对输入框值更新的响应-----' + value + '-------------') if (type === 1) { setSearchVal(value || '-') } if (type === 2) { startTransition(() => { setSearchVal(value || '-') }) } }, [value, type]); return (
    setValue(e.target.value)} />
    setTpye(1)}>normal
    setTpye(2)}>transiton
    ); };

    普通模式下

    1.gif

    如图所示:连续输入字符123,当第一个字符输入后,搜索值马上响应,列表渲染立刻开始,造成卡顿输入框停止了对用户输入的响应,直到渲染结束,输入框才继续响应。

    自学 PHP、MySQL和Apache
    自学 PHP、MySQL和Apache

    本书将PHP开发与MySQL应用相结合,分别对PHP和MySQL做了深入浅出的分析,不仅介绍PHP和MySQL的一般概念,而且对PHP和MySQL的Web应用做了较全面的阐述,并包括几个经典且实用的例子。 本书是第4版,经过了全面的更新、重写和扩展,包括PHP5.3最新改进的特性(例如,更好的错误和异常处理),MySQL的存储过程和存储引擎,Ajax技术与Web2.0以及Web应用需要注意的安全

    下载

    使用startTransition后

    2.gif

    如图所示:连续输入字符123,输入框不断响应,搜索值的响应被延后,保证页面反馈,直到输入结束,才开始响应搜索值,渲染搜索结果,保持页面响应。

    4. useTransiton

    useTransiton使用介绍

    import { useTransiton } from 'react'
    
    const [isPending, startTransition] = useTransiton({timeoutMs: 2000})
    // 例如, 在pending状态下,您可以展示一个Spinner
    { isPending ? < Spinner /> : null }
    • startTransition 是一个接受回调的函数,用于告知React需要延迟更新的state。
    • isPending 是一个布尔值,这是react告知我们是否等待过渡完成的方式。
    • useTransition 接受带有 timeoutMs 的延迟响应的值,如果给定的timeoutMs内未完成,它将会强制执行startTransition回调函数内state的更新。

    useTransiton简单分析

    我们通过伪代码理解下useTransition

    function useTransition(){
        const [isPending, setPending] = mountState(false);
        const start = (callback)=>{
            setPending(true);
            // Scheduler.unstable_next 通过 transiton 模式,低优先级调度执行回调函数
            // 可以降低更新的优先级。如果回调中触发的更新优先级会比较低,
            // 它会让位为高优先级的更新,或者当前事务繁忙时,调度到下一空闲期再应用。
            Scheduler.unstable_next(() => {
                const prevTransition = ReactCurrentBatchConfig.transition;
                ReactCurrentBatchConfig.transition = 1;
                try {
                    setPending(false);
                    //实行回调函数
                    callback();
                } finally {
                    ReactCurrentBatchConfig.transition = prevTransition;
                }
            })
        }
        return [isPending, start];
    }

    startTransition执行过程中,会触发两次setPending ,一次在transition=1之前,一次在之后。startTransition被调用时setPending(true),当startTransition内部的回调函数执行时transiton过渡任务更新setPending(false)。react内部可以根据pending值的变化准确把握等待的过渡时间,并依此判断是否超过了timeoutMs(如果有传入)强制执行更新。

    5. useDeferredValue

    useDeferredValue使用介绍

    const [value, setValue] = useState('')
    // defferedValue值延后于state更新
    const deferredValue = useDeferredValue(value, {timeoutMs: 2000})
    • useDeferredValue 返回一个延迟响应的状态,可以设置最长延迟时间timeoutMs
    • 可以传入可选的timeoutMs,如果给定的timeoutMs内未完成,它将会强制更新。
    • 与useTransition的不同: useTransition是处理一段逻辑,而useDeferred是产生一个新状态

    useDeferredValue的使用

    import React, { useEffect, useState, useTransition, useDeferredValue } from 'react';
    import './App.css'
    
    const SearchResult = (props) => {
        const resultList = props.query
            ? Array.from({ length: 10000 }, (_, index) => ({
                id: index,
                keyword: `${props.query} -- 搜索结果${index}`,
            })) : [];
        return resultList.map(({ id, keyword }) => (
            
  • {keyword}
  • )) } const App = () => { const [value, setValue] = useState(''); const searchValue = useDeferredValue(value, { timeoutMs: 2000 }); useEffect(() => { console.log('对输入框值的响应--------' + value + '---------------') }, [value]) useEffect(() => { // 监听搜索值改变 console.log('对搜索值的更新响应++++++' + searchValue + '+++++++++++') }, [searchValue]) return (
    setValue(e.target.value)} />
    useDeferredValue
    ); };

    3.gif

    useDeferredValue简单分析

    我们通过伪代码理解下useDeferredValue

    function useDeferredValue(value){
        const [prevValue, setValue] = updateState(value);
        updateEffect(() => {
            // 在 useEffect 中通过 transition 模式来更新 value 。
            Scheduler.unstable_next(() => {
                const prevTransition = ReactCurrentBatchConfig.transition;
                ReactCurrentBatchConfig.transition = 1;
                try {
                    setValue(value);
                } finally {
                    ReactCurrentBatchConfig.transition = prevTransition;
                }
             })
        }, [value]);
        return prevValue;
    }

    useDeferredValue通过useEffect监听传入值的变化,然后通过过渡任务执行值的改变。这样保证defrredValue的更新滞后于setState,同时符合过渡更新的原则,因为是通过transition 调度机制执行的。

    更多编程相关知识,请访问:编程视频!!

    相关专题

    更多
    css3transition
    css3transition

    css3transition属性用于指定如何从一个CSS样式过渡到另一个CSS样式,本专题为大家提供transition相关的文章、相关下载和相关课程,大家可以免费体验。

    230

    2023.06.27

    常用的数据库软件
    常用的数据库软件

    常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

    970

    2023.11.02

    内存数据库有哪些
    内存数据库有哪些

    内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

    631

    2023.11.14

    mongodb和redis哪个读取速度快
    mongodb和redis哪个读取速度快

    redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    479

    2024.04.02

    redis怎么做缓存服务器
    redis怎么做缓存服务器

    redis 作为缓存服务器的答案:redis 是一款开源、高性能、分布式的键值存储,可作为缓存服务器使用。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    399

    2024.04.07

    redis怎么解决数据一致性
    redis怎么解决数据一致性

    redis 提供了两种一致性模型,以维护副本数据一致性:强一致性 (sync) 确保写操作仅在复制到所有从节点后才完成;最终一致性 (async) 则在主节点上写操作后认为已完成,牺牲一致性换取性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    391

    2024.04.07

    mysql和redis怎么保证双写一致性
    mysql和redis怎么保证双写一致性

    确保 mysql 和 redis 双写一致性的技术包括:1、事务性更新:同时更新 mysql 和 redis,保证一致性;2、主从复制:mysql 主服务器更改同步到 redis 从服务器;3、基于事件的更新:mysql 记录更改并发送到 redis等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    444

    2024.04.07

    redis缓存一般存些什么数据
    redis缓存一般存些什么数据

    redis缓存中存储的数据类型包括:字符串、哈希、列表、集合、有序集合、位图、地理空间数据和hyperloglog。这些数据类型适用于存储各种数据,从简单信息到复杂对象和地理位置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    403

    2024.04.07

    高德地图升级方法汇总
    高德地图升级方法汇总

    本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

    72

    2026.01.16

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    CSS3实现按钮特效视频教程
    CSS3实现按钮特效视频教程

    共15课时 | 3.2万人学习

    CSS3 3D 特效视频教程
    CSS3 3D 特效视频教程

    共14课时 | 3万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号