中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

react18中的Transition怎么用

發布時間:2022-03-25 11:05:34 來源:億速云 閱讀:289 作者:iii 欄目:web開發

這篇文章主要介紹“react18中的Transition怎么用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“react18中的Transition怎么用”文章能幫助大家解決問題。

react18中的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>
    );
};

普通模式下

react18中的Transition怎么用

如圖所示:連續輸入字符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 調度機制執行的。

關于“react18中的Transition怎么用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

松溪县| 赣榆县| 茌平县| 通州市| 阿拉善左旗| 天长市| 饶阳县| 邹平县| 永清县| 宝丰县| 赤城县| 民权县| 临夏市| 上饶市| 平罗县| 宜都市| 安国市| 武隆县| 信丰县| 陵川县| 大同市| 门头沟区| 宁安市| 政和县| 泗洪县| 菏泽市| 寿宁县| 承德县| 雷波县| 威信县| 蓝山县| 淄博市| 嵊州市| 文山县| 宜川县| 南乐县| 神池县| 聂拉木县| 仁化县| 武川县| 黎平县|