Heim > Artikel > Web-Frontend > Eine kurze Analyse des neuen Konzepts Transition in React18
Dieser Artikel führt Sie in das neue Konzept von Transition in React18 ein und stellt kurz die Verwendung der neuen API vor: startTransition und der neuen Hooks: useTransition und usedeferredValue. Ich hoffe, dass er für alle hilfreich ist!
React 18 führt ein neues Konzept ein – transition
, das eine neue API – startTransition
und zwei neue Hooks – useTransition
und mit sich bringt usedeferredValue
, dieser Artikel beginnt mit einer Einführung für Erstanwender. [Verwandte Empfehlungen: Redis-Video-Tutorial]transition
,由此带来了一个新的API——startTransition
和两个新的hooks——useTransition
和usedeferredValue
,本文由此展开使用尝鲜介绍。【相关推荐:Redis视频教程】
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
通过演示对比
这是一个对输入字符后展示搜索结果的场景模拟,通过伪造大量搜索结果,模拟容易卡顿的情况。
我们试着连续输入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
tansition
Ursprüngliche AbsichtstartTransition
Verwendung und EinführunguseTransition
Verwendung und EinführunguseDeferredValue
Verwendung und Einführung transtion
Direkte Übersetzung für transition
. Tansition wird im Wesentlichen vorgeschlagen, um das Problem der Rendering-Parallelität
zu lösen. Sobald sich in React der Komponentenstatus ändert und ein erneutes Rendern ausgelöst wird, kann das Rendern nicht gestoppt werden. Die Seite kann nicht weiter auf Benutzerinteraktionen reagieren, bis die Komponente erneut gerendert wird. 🎜🎜Aus diesem Grund können Updates in React 18 in die folgenden zwei Kategorien unterteilt werden: 🎜Emergency Update
(urgent update): Update-Vorgänge, bei denen Benutzer eine sofortige Reaktion erwarten, wie z B. Mausklicks oder Tastatureingaben. Übergangsaktualisierung
(Übergangsaktualisierung): Einige Aktualisierungsvorgänge mit akzeptabler Verzögerung, z. B. Abfragezeit, Suchempfehlungen, Anzeige von Suchergebnissen usw. 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]; }🎜Das durch
startTrionstion
in React 18 gekennzeichnete Update ist ein Übergangsupdate (die Priorität der Ausführung ist reduziert. Zu diesem Zeitpunkt wird React entsprechend der internen Planung verzögert). Mechanismus Führt interne Statusaktualisierungen durch. 🎜🎜Entwickler in der Entwicklung können durch Übergangs-Hooks entscheiden, welche Updates als Übergangsereignisse markiert werden. Sobald es markiert ist, stellt es eine Ausführung mit niedriger Priorität dar, das heißt, React weiß, dass sich der Status bei der Aktualisierung verzögern kann Benutzerinteraktionserlebnis. Halten Sie die Seiten reaktionsfähig. 🎜🎜3. startTransiton🎜🎜Einführung in die Verwendung von startTransiton🎜const [value, setValue] = useState('') // defferedValue值延后于state更新 const deferredValue = useDeferredValue(value, {timeoutMs: 2000})🎜Zuallererst , stellen wir das einfachste vorstartTransition🎜
value
(dringende Aktualisierung) und die Änderungen des Suchwerts searchVal
(Übergangsaktualisierung) zu überwachen und sie in der Steuerleiste auszugeben . 🎜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> ); };🎜Normalmodus🎜🎜🎜🎜
Wie im Bild gezeigt:
Geben Sie fortlaufend 123 Zeichen ein. Wenn das erste Zeichen eingegeben wird, reagiert der Suchwert sofort und die Listenwiedergabe beginnt sofort Verzögerung: Das Eingabefeld reagiert nicht mehr auf Benutzereingaben und reagiert erst dann weiter, wenn das Rendern beendet ist. 🎜🎜Nach der Verwendung von startTransition🎜🎜🎜🎜Wie im Bild gezeigt:
Geben Sie fortlaufend 123 Zeichen ein, das Eingabefeld antwortet weiterhin und die Antwort auf den Suchwert wird verzögert, um eine Seitenrückmeldung sicherzustellen Die Eingabe ist abgeschlossen. Beginnen Sie mit der Reaktion auf Suchwerte, der Darstellung von Suchergebnissen und der Aufrechterhaltung der Reaktionsfähigkeit der Seite. 🎜🎜4. useTransiton🎜🎜Einführung in die Verwendung von Transiton🎜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; }
isPending
ist ein boolescher Wert, mit dem React uns mitteilt, ob wir auf den Abschluss des Übergangs warten sollen. useTransition
akzeptiert einen verzögerten Antwortwert mit timeoutMs
. Wenn er nicht innerhalb der angegebenen timeoutMs abgeschlossen wird, wird die Ausführung von startTransition erzwungen
Aktualisierung des Status in der Rückruffunktion. useTransition
durch Pseudocode. 🎜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 调度机制执行的。
更多编程相关知识,请访问:编程视频!!
Das obige ist der detaillierte Inhalt vonEine kurze Analyse des neuen Konzepts Transition in React18. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!