react startTransition过渡任务

任务优先级:
	在React18之前,所有的更新任务都被视为急迫的任务
	在React18诞生了concurrentMode模式,在这个模式下,渲染是可以中断,低优先级任务,可以让高优先级的任务先更新渲染。
	可以说React18更青睐于良好的用户体验。从concurrentMode到susponse再到startTransition无疑都是围绕着更优质的用户体验展开

任务优先级场景:
	有一个input表单,并且有一个大量数据的列表,通过表单输入内容,对列表数据进行搜索,过滤。那么在这种情况下,就存在了多个并发的更新任务。分别为

		第一种:input表单要实时获取状态,所以是受控的,那么更新input的内容,就要触发更新任务。
		第二种:input内容改变,过滤列表,重新渲染列表也是一个任务。
	
	当过滤列表过多时,输入内容就会产生卡顿
	
	第一种类型的更新,在输入的时候,希望是的视觉上马上呈现变化,高优先级。
	第二种类型的更新就是根据数据的内容,去过滤列表中的数据,渲染列表,这个种类的更新,和上一种比起来优先级就没有那么高。

与定时器的区别:
	1.由于setTimeout本身也是一个宏任务,而每一次触发dom回调也是宏任务,所以setTimeout还是会影响页面的交互体验。
		在concurrent Mode模式下,startTransition是可以中断渲染的,所以它不会让页面卡顿,React让这些任务,在浏览器空闲时间执行
		和window.requestAnimation类似
	2.startTransition的回调函数是同步执行的。
		在startTransition之中任何更新,都会标记上transition,React将在更新的时候,判断这个标记来决定是否完成此次更新。
		所以Transition可以理解成比setTimeout更早的更新。
		但是同时要保证ui的正常响应,在性能好的设备上,transition两次更新的延迟会很小,但是在慢的设备上,延时会很大,但是不会影响UI的响应。


(1)开启concurrent Mode模式:
	import ReactDOM from 'react-dom'
	const root =  ReactDOM.createRoot(document.getElementById('app'))
	root.render(<App/>)


(2)使用startTranstion
	const handleChange=()=>{
 
    setInputValue(e.target.value)	 /* 高优先级任务 —— 改变搜索条件 */
   
    React.startTransition(()=>{		 /* 低优先级任务 —— 改变搜索过滤后列表状态  */
        setSearchQuery(e.target.value)
    })
}

代码示例:

/*  模拟数据  */
const mockDataArray = new Array(10000).fill(1)
/* 高量显示内容 */
function ShowText({
     
      query }){
    
    
   const text = 'asdfghjk'
   let children
   if(text.indexOf(query) > 0 ){
    
    
       /* 找到匹配的关键词 */
       const arr = text.split(query)
       children = <div>{
    
    arr[0]}<span style={
    
    {
    
     color:'pink' }} >{
    
    query}</span>{
    
    arr[1]} </div>
   }else{
    
    
      children = <div>{
    
    text}</div>
   }
   return <div>{
    
    children}</div>
}
/* 列表数据 */
function List ({
     
      query }){
    
    
    console.log('List渲染')
    return <div>
        {
    
    
           mockDataArray.map((item,index)=><div key={
    
    index} >
              <ShowText query={
    
    query} />
           </div>)
        }
    </div>
}
/* memo 做优化处理  */
const NewList = memo(List)
========================================================================================================
export default function App(){
    
    
    const [ value ,setInputValue ] = React.useState('')
    const [ isTransition , setTransion ] = React.useState(false)
    const [ query ,setSearchQuery  ] = React.useState('')
    const handleChange = (e) => {
    
    
        /* 高优先级任务 —— 改变搜索条件 */
        setInputValue(e.target.value)
        if(isTransition){
    
     /* transition 模式 */
            React.startTransition(()=>{
    
    
                /* 低优先级任务 —— 改变搜索过滤后列表状态  */
                setSearchQuery(e.target.value)
            })
        }else{
    
     /* 不加优化,传统模式 */
            setSearchQuery(e.target.value)
        }
    }
    return <div>
        <button onClick={
    
    ()=>setTransion(!isTransition)} >{
    
    isTransition ? 'transition' : 'normal'} </button>
        <input onChange={
    
    handleChange}
            placeholder="输入搜索内容"
            value={
    
    value}
        />
       <NewList  query={
    
    query} />
    </div>
}

おすすめ

転載: blog.csdn.net/weixin_43294560/article/details/121428531