この記事では、react18 の Transition の新しい概念を理解し、新しい API: startTransition と新しいフック: useTransition と usedeferredValue の使用法を簡単に紹介します。
React 18 では、新しい概念 - transition
が導入され、新しい API - startTransition
と 2 つの新しいフックが導入されました。 - useTransition
と usedeferredValue
、この記事はアーリーアダプターの紹介から始まります。 [関連する推奨事項: Redis ビデオ チュートリアル ]
1. 概要
この記事は 4 つの部分に分かれています。
本来の目的
使用方法と紹介
使用方法と紹介
使用と紹介
#2. 移行の本来の目的
transtion は、直訳すると
トランジション となります。 Tansition は本質的に
レンダリングの同時実行性の問題を解決するために提案されたものです。 React では、コンポーネントの状態が変化して再レンダリングがトリガーされると、レンダリングを停止することはできません。コンポーネントが再レンダリングされるまで、ページはユーザーの操作に応答し続けることはできません。 このため、react 18 のアップデートは次の 2 つのカテゴリに分類できます:
// 被startTransiton标记后为过渡更新 startTransition(()=> { // 非紧急更新,会被降低优先级,延迟执行 setQueryValue(inputValue) }) // 未被标记则马上执行 setInputValue(inputValue)
でマークされたアップデートは過渡的なアップデート (実行の優先度が下がる) であり、この時点で、react は内部の仕様に従って実行を遅らせます。スケジューリング メカニズム 内部状態の更新。 開発中に、開発者は移行フックを通じてどの更新を移行イベントとしてマークするかを決定できます。マークが付けられると、それは優先度の低い実行を表します。つまり、react は状態の更新が遅れる可能性があることを認識しています。
優先度の高いイベントは応答性を維持でき、 更新の優先度が向上します。ユーザー インタラクション エクスペリエンスを維持し、ページの応答
を維持します。
3. startTransiton
startTransiton の使い方の紹介const handleClick = () => {
// startTransition包裹标记为低优先级更新
startTransition(()=> {
setQueryValue(inputValue)
})
// 未被标记则马上执行
setInputValue(inputValue)
}
startTransiton はコールバックを受け取り、状態を遅延させる必要があることを React に伝えるために使用される関数です。
文字入力後に検索結果を表示するシナリオシミュレーションであり、大量の検索結果を捏造することでフリーズしやすい状況をシミュレーションします。
連続して 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(''); 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文字を連続して入力します。 first 文字が入力されると、検索値がすぐに応答し、リストのレンダリングがすぐに開始されるため、入力ボックスがフリーズし、ユーザー入力に応答しなくなります。レンダリングが完了するまで、入力ボックスは応答を続けません。startTransition使用後
図のように、
123文字を連続して入力すると、ボックスは応答し続けます。ページのフィードバックを確保するために検索値への応答は遅延されます。入力が終了するまで検索値への応答は開始されず、検索結果が表示され、ページの応答性が維持されます。useTransiton の使い方の紹介
import { useTransiton } from 'react' const [isPending, startTransition] = useTransiton({timeoutMs: 2000}) // 例如, 在pending状态下,您可以展示一个Spinner { isPending ? < Spinner /> : null }
isPending
useTransition の遅延応答を持つ値を受け入れます。指定された 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('') // defferedValue值延后于state更新 const deferredValue = useDeferredValue(value, {timeoutMs: 2000})
timeoutMs
。一段逻辑
,而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 の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。