React18Transition&startTransiton&useTransiton&useDeferredValue
时间:2023-03-28 01:22:53
HTML
React18引入了一个新的概念——transition,它带来了一个新的API——startTransition和两个新的hooks——useTransition和useddeferredValue。1)transition的本意是transition直接译为transition。Tansition本质上是为了解决渲染并发的问题而提出的。在React中,一旦组件状态发生变化并触发重新渲染,就无法停止渲染。在重新呈现组件之前,页面无法继续响应用户交互。为此,react18中的更新可以分为以下两类:紧急更新:用户希望立即响应的更新操作,例如鼠标点击或键盘输入。过渡更新(transitionupdate):一些可以接受延迟的更新操作,比如查询、搜索推荐、搜索结果的显示等。//被startTransiton标记后,就是一个过渡更新startTransition(()=>{//非紧急更新会降低优先级,执行setQueryValue(inputValue)})//如果没有标记,立即执行setInputValue(inputValue)在react18中startTriontion标记的更新为过渡更新(优先级执行率降低)。这时候react会根据内部的调度机制延迟内部状态更新的执行。在开发过程中,开发人员可以使用转换挂钩来确定哪些更新被标记为转换事件。一旦被标记,则意味着低优先级执行,即react知道状态可以延迟更新,通过区分更新优先级,高优先级事件可以保持响应,提升用户交互体验,保持页面响应性。2)startTransitonstartTransitonuseintroductionconsthandleClick=()=>{//startTransition包被标记为低优先级更新startTransition(()=>{setQueryValue(inputValue)})//如果没有标记,先执行setInputValue(inputValue)}下面介绍一个最简单的startTransition。startTransiton是一个函数,它接受一个回调来通知React需要延迟的状态。如果状态更新会导致组件挂起,则应将其包装在startTransition中。这是一个输入字符后显示搜索结果的场景模拟。通过伪造大量搜索结果,模拟容易卡住的情况。我们尝试连续输入123,监听搜索框value值的变化(紧急更新)和搜索值searchVal的变化(transitionupdate)并输出到控制栏。从“反应”中导入反应,{useEffect,useState,startTransition};import'./index.css'constSearchResult=(props)=>{constresultList=props.query?Array.from({length:100000},(_,index)=>({id:index,keyword:`${props.query}--搜索结果${index}`,})):[];returnresultList.map(({id,keyword})=>({keyword}))}exportdefault()=>{const[type,setType]=useState(1)const[值,setValue]=useState('');const[searchVal,setSearchVal]=useState('');useEffect(()=>{//监听搜索值变化console.log('响应搜索值更新++++++'+searchVal+'+++++++++++')},[searchVal])useEffect(()=>{//监听输入框值变化console.log('响应输入框值更新-----'+value+'------------')},[值])useEffect(()=>{if(type===1){setSearchVal(value)}if(type===2){startTransition(()=>{setSearchVal(value)})}},[价值]);返回(<divclassName='App'>StartTransition
setValue(e.target.value)}/>setType(1)}>normal
setType(2)}>transiton );}startTransition模式和普通模式setTimeout的区别就是上面setSearchQuery的例子。使用setTimeout也可以达到类似的目的。那么startTransition和setTimeout有什么区别呢?一个重要的区别是setTimeout是“延迟”执行,startTransition立即执行,传递给startTransition的函数同步运行,但它里面的所有更新都会被标记为非紧急,React会在处理更新时决定如何呈现这些laterupdates,也就是说会比setTimeout中的update早渲染。还有一个很重要的区别是,如果包裹在setTimeout中,如果是大规模的更新操作,页面会被阻塞,无法交互,直到超时。此时,用户输入、键盘按下等紧急更新操作将被阻塞。而startTransition则不同,因为它标记的更新都是可中断的,所以不会阻塞UI交互。即使用户输入发生变化,React也不必一直渲染用户不再感兴趣的内容。最后,因为setTimeout是异步执行的,即使只是显示一个小加载也需要编写异步代码。通过过渡,React可以使用钩子来跟踪过渡的执行状态,并根据过渡的当前状态更新加载。3)useTransitionuseTransitionimport{useTransition}from'react'const[isPending,startTransition]=useTransition({timeoutMs:2000})//比如在pending状态下,可以显示一个Spinner{isPending?
:null}startTransition是一个函数,它接受一个回调来告诉React状态需要延迟。isPending是一个布尔值,这是React告诉我们是否等待转换完成的方式。useTransition接受带有timeoutMs的延迟响应的值,如果在给定的timeoutMs内没有完成,它将强制更新startTransition回调函数中的状态。importReact,{useEffect,useState,useTransition}from'react';import'./index.css'constSearchResult=(props)=>{constresultList=props.query?Array.from({length:100000},(_,index)=>({id:index,keyword:`${props.query}--搜索结果${index}`,})):[];returnresultList.map(({id,keyword})=>(
{keyword}))}exportdefault()=>{const[type,setType]=useState(1)const[值,setValue]=useState('');const[searchVal,setSearchVal]=useState('');const[loading,startTransition]=useTransition({timeoutMs:2000});useEffect(()=>{//监听搜索值变化console.log('yesResponsetosearchvalueupdate++++++'+searchVal+'++++++++++++')},[searchVal])useEffect(()=>{//监听输入框值变化console.log('响应输入框值更新-----'+value+'------------')},[value])useEffect(()=>{if(type===1){setSearchVal(value)}if(type===2){startTransition(()=>{setSearchVal(值)})}},[值]);返回(UseTransition
setValue(e.target.value)}/>setType(1)}>normal