ホームページ  >  記事  >  ウェブフロントエンド  >  React18 の新しいコンセプト Transition の簡単な分析

React18 の新しいコンセプト Transition の簡単な分析

青灯夜游
青灯夜游転載
2022-03-25 10:52:462451ブラウズ

この記事では、react18 の Transition の新しい概念を理解し、新しい API: startTransition と新しいフック: useTransition と usedeferredValue の使用法を簡単に紹介します。

React18 の新しいコンセプト Transition の簡単な分析

React 18 では、新しい概念 - transition が導入され、新しい API - startTransition と 2 つの新しいフックが導入されました。 - useTransitionusedeferredValue、この記事はアーリーアダプターの紹介から始まります。 [関連する推奨事項: Redis ビデオ チュートリアル ]

1. 概要

この記事は 4 つの部分に分かれています。

  • ##tansition 本来の目的
  • startTransition 使用方法と紹介
  • useTransition 使用方法と紹介
  • useDeferredValue 使用と紹介

#2. 移行の本来の目的

transtion は、直訳すると トランジション となります。 Tansition は本質的に レンダリングの同時実行性の問題を解決するために提案されたものです。 React では、コンポーネントの状態が変化して再レンダリングがトリガーされると、レンダリングを停止することはできません。コンポーネントが再レンダリングされるまで、ページはユーザーの操作に応答し続けることはできません。 このため、react 18 のアップデートは次の 2 つのカテゴリに分類できます:

    緊急アップデート
  • (緊急アップデート): ユーザーが期待するアップデート操作マウスのクリックやキーボード入力など、すぐに応答します。
  • 移行更新
  • (移行更新): クエリ時間、検索の推奨事項、検索結果の表示など、許容可能な遅延を持つ一部の更新操作。
    // 被startTransiton标记后为过渡更新
    startTransition(()=> {
        // 非紧急更新,会被降低优先级,延迟执行
        setQueryValue(inputValue)
    })
    
    // 未被标记则马上执行
    setInputValue(inputValue)
  • react 18 では、
startTrionstion

でマークされたアップデートは過渡的なアップデート (実行の優先度が下がる) であり、この時点で、react は内部の仕様に従って実行を遅らせます。スケジューリング メカニズム 内部状態の更新。 開発中に、開発者は移行フックを通じてどの更新を移行イベントとしてマークするかを決定できます。マークが付けられると、それは優先度の低い実行を表します。つまり、react は状態の更新が遅れる可能性があることを認識しています。

更新優先度を区別することにより、

優先度の高いイベントは応答性を維持でき、 更新の優先度が向上します。ユーザー インタラクション エクスペリエンスを維持し、ページの応答 を維持します。

3. startTransiton

startTransiton の使い方の紹介

const handleClick = () => {
    // startTransition包裹标记为低优先级更新
    startTransition(()=> {
        setQueryValue(inputValue)
    })
    
    // 未被标记则马上执行
    setInputValue(inputValue)
}
まず、最も単純なものを紹介しましょう。

startTransition

startTransiton はコールバックを受け取り、状態を遅延させる必要があることを React に伝えるために使用される関数です。
    #特定の状態の更新によってコンポーネントがハングする場合は、startTransition でラップする必要があります
デモによる比較

文字入力後に検索結果を表示するシナリオシミュレーションであり、大量の検索結果を捏造することでフリーズしやすい状況をシミュレーションします。

連続して 123 を入力して、検索ボックスの値

value

(緊急更新) と検索値

searchVal (遷移更新) の変化を監視します。コントロールバーに出力します。

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(&#39;&#39;);
    const [searchVal, setSearchVal] = useState(&#39;-&#39;);

    useEffect(() => {
        // 监听搜索值改变
        console.log(&#39;对搜索值更新的响应++++++&#39; + searchVal + &#39;+++++++++++&#39;)
    }, [searchVal])

    useEffect(() => {
        console.log(&#39;对输入框值更新的响应-----&#39; + value + &#39;-------------&#39;)
        if (type === 1) {
            setSearchVal(value || &#39;-&#39;)
        }
        if (type === 2) {
            startTransition(() => {
                setSearchVal(value || &#39;-&#39;)
            })
       }
    }, [value, type]);

    return (
        <div className=&#39;App&#39;>
            <input value={value} onChange={e => setValue(e.target.value)} />
            <div className={`type_button ${type === 1 ? &#39;type_button_checked&#39; : &#39;&#39;}`} onClick={() => setTpye(1)}>normal</div>
            <div className={`type_button ${type === 2 ? &#39;type_button_checked&#39; : &#39;&#39;}`} onClick={() => setTpye(2)}>transiton</div>
            <ul>
                <SearchResult query={searchVal}></SearchResult>
            </ul>
        </div>
    );
};
通常モードの場合

React18 の新しいコンセプト Transition の簡単な分析図のように、

123文字を連続して入力します。 first 文字が入力されると、検索値がすぐに応答し、リストのレンダリングがすぐに開始されるため、入力ボックスがフリーズし、ユーザー入力に応答しなくなります。レンダリングが完了するまで、入力ボックスは応答を続けません。

startTransition使用後

React18 の新しいコンセプト Transition の簡単な分析図のように、

123文字を連続して入力すると、ボックスは応答し続けます。ページのフィードバックを確保するために検索値への応答は遅延されます。入力が終了するまで検索値への応答は開始されず、検索結果が表示され、ページの応答性が維持されます。

4. useTransiton

useTransiton の使い方の紹介

import { useTransiton } from &#39;react&#39;

const [isPending, startTransition] = useTransiton({timeoutMs: 2000})
// 例如, 在pending状态下,您可以展示一个Spinner
{ isPending ? < Spinner /> : null }

startTransition
    はコールバックを受け入れ、遅延する必要がある状態を React に通知するために使用される関数です。
  • isPending
  • はブール値で、遷移が完了するまで待つかどうかを React が伝える方法です。
  • useTransition
  • timeoutMs の遅延応答を持つ値を受け入れます。指定された timeoutMs 以内に完了しない場合は、startTransition# の実行が強制されます。 ## コールバック関数内の状態の更新。 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(&#39;&#39;)
// defferedValue值延后于state更新
const deferredValue = useDeferredValue(value, {timeoutMs: 2000})
  • useDeferredValue 返回一个延迟响应的状态,可以设置最长延迟时间timeoutMs
  • 可以传入可选的timeoutMs,如果给定的timeoutMs内未完成,它将会强制更新。
  • 与useTransition的不同: useTransition是处理一段逻辑,而useDeferred是产生一个新状态

useDeferredValue的使用

import React, { useEffect, useState, useTransition, useDeferredValue } from &#39;react&#39;;
import &#39;./App.css&#39;

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(&#39;&#39;);
    const searchValue = useDeferredValue(value, { timeoutMs: 2000 });

    useEffect(() => {
        console.log(&#39;对输入框值的响应--------&#39; + value + &#39;---------------&#39;)
    }, [value])

    useEffect(() => {
        // 监听搜索值改变
        console.log(&#39;对搜索值的更新响应++++++&#39; + searchValue + &#39;+++++++++++&#39;)
    }, [searchValue])

    return (
        <div className=&#39;App&#39;>
            <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>
    );
};

React18 の新しいコンセプト Transition の簡単な分析

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 の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。