首页前端开发其他前端知识React中Transition的概念是什么,如何使用

React中Transition的概念是什么,如何使用

时间2024-03-26 13:24:03发布访客分类其他前端知识浏览1245
导读:这篇文章给大家分享的是“React中Transition的概念是什么,如何使用”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“React中Transition的概念是...
这篇文章给大家分享的是“React中Transition的概念是什么,如何使用”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“React中Transition的概念是什么,如何使用”吧。




React 18中,引入了一个新概念——transition,由此带来了一个新的API——startTransition和两个新的hooks——useTransitionusedeferredValue,本文由此展开使用尝鲜介绍。

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 }
    ) =>
 (
        li key={
id}
    >
{
keyword}
    /li>

    ))
}
    

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 (
        div className='App'>

            input value={
value}
 onChange={
    e =>
 setValue(e.target.value)}
     />

            div className={
`type_button ${
type === 1 ? 'type_button_checked' : ''}
`}
 onClick={
    () =>
 setTpye(1)}
    >
    normal/div>

            div className={
`type_button ${
type === 2 ? 'type_button_checked' : ''}
`}
 onClick={
    () =>
 setTpye(2)}
    >
    transiton/div>
    
            ul>

                SearchResult query={
searchVal}
    >
    /SearchResult>
    
            /ul>
    
        /div>
    
    );

}
    ;

普通模式下

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

使用startTransition后

如图所示:连续输入字符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 }
    ) =>
 (
        li key={
id}
    >
{
keyword}
    /li>

    ))
}
    

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

    const searchValue = useDeferredValue(value, {
 timeoutMs: 2000 }
    );
    

    useEffect(() =>
 {

        console.log('对输入框值的响应--------' + value + '---------------')
    }
    , [value])

    useEffect(() =>
 {

        // 监听搜索值改变
        console.log('对搜索值的更新响应++++++' + searchValue + '+++++++++++')
    }
    , [searchValue])

    return (
        div className='App'>

            input value={
value}
 onChange={
    e =>
 setValue(e.target.value)}
     />

        div className={
`type_button type_button_checked`}
    >
    useDeferredValue/div>
    
        ul>

            SearchResult query={
searchValue}
    >
    /SearchResult>
    
        /ul>
    
    /div>
    
    );

}
    ;

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 调度机制执行的。


以上就是关于“React中Transition的概念是什么,如何使用”的相关知识,感谢各位的阅读,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注网络,小编每天都会为大家更新不同的知识。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

Transition

若转载请注明出处: React中Transition的概念是什么,如何使用
本文地址: https://pptw.com/jishu/653527.html
Golang中循环处理语句以及用法是怎样 Go语言中怎么删除map元素,方法是什么

游客 回复需填写必要信息