Home >Web Front-end >JS Tutorial >A brief analysis of the new concept Transition in react18
This article will take you to understand the new concept of Transition in react18, and briefly introduce the use of the new API: startTransition and new hooks: useTransition and usedeferredValue. I hope it will be helpful to everyone!
In React 18, a new concept is introduced - transition
, which brings a new API - startTransition
and two new hooks - useTransition
and usedeferredValue
, this article starts with an early adopter introduction. [Related recommendations: Redis Video Tutorial]
1. Overview
This article is divided into 4 parts:
tansition
Original intentionstartTransition
Use and introductionuseTransition
Use and introductionuseDeferredValue
Use and introduction2. Original intention of transition
transtion
is directly translated as transition
. Tansition is essentially proposed to solve the problem of rendering concurrency
. In React, once the component state changes and a re-render is triggered, rendering cannot be stopped. The page cannot continue to respond to user interaction until the component is re-rendered.
For this reason, updates in react 18 can be divided into the following two categories:
Emergency update
(urgent update): update operations that users expect to respond immediately, Such as mouse clicks or keyboard input. Transition update
(transition update): Some update operations with acceptable delay, such as query time, search recommendations, display of search results, etc. // 被startTransiton标记后为过渡更新 startTransition(()=> { // 非紧急更新,会被降低优先级,延迟执行 setQueryValue(inputValue) }) // 未被标记则马上执行 setInputValue(inputValue)
In react 18, the update marked by startTrionstion
is a transitional update (the priority of execution is reduced). At this time, react will delay execution according to the internal scheduling mechanism. Internal state update.
During development, developers can decide which updates are marked as transition events through transition hooks. Once marked, it represents a low-priority execution, that is, react knows that the state can be delayed in updating. By distinguishing the update priority
, high-priority events can remain responsive, improve the user interaction experience, and maintain Page response
.
3. startTransiton
Introduction to the use of startTransiton
const handleClick = () => { // startTransition包裹标记为低优先级更新 startTransition(()=> { setQueryValue(inputValue) }) // 未被标记则马上执行 setInputValue(inputValue) }
First of all, let’s introduce the simplest The startTransition
Comparison through demonstration
This is a scenario simulation of displaying search results after entering characters. By forging a large number of search results, it simulates the situation where it is easy to freeze.
We try to continuously enter 123, monitor the change of the search box value value
(urgent update) and the change of the search value searchVal
(transition update) and output them to the control bar.
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> ); };
In normal mode
As shown in the figure:
Enter 123 characters continuously. When the first After characters are entered, the search value responds immediately, and list rendering starts immediately, causing the input box to freeze and stop responding to user input. The input box does not continue to respond until the rendering is completed.
After using startTransition
As shown in the figure:
Enter 123 characters continuously, and the input box continues to respond , the response to the search value is delayed to ensure page feedback. It does not start responding to the search value until the end of the input, rendering the search results, and keeping the page responsive.
4. useTransiton
useTransiton usage introduction
import { useTransiton } from 'react' const [isPending, startTransition] = useTransiton({timeoutMs: 2000}) // 例如, 在pending状态下,您可以展示一个Spinner { isPending ? < Spinner /> : null }
startTransition
is a function that accepts callbacks and is used to inform React of the state that needs to be delayed. isPending
is a boolean value, which is react's way of telling us whether to wait for the transition to complete. useTransition
Accepts a value with a delayed response of timeoutMs
. If it is not completed within the given timeoutMs, it will force the execution of startTransition
Update of state within the callback function. Simple analysis of useTransiton
We understand useTransition
through pseudo code.
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 调度机制执行的。
更多编程相关知识,请访问:编程视频!!
The above is the detailed content of A brief analysis of the new concept Transition in react18. For more information, please follow other related articles on the PHP Chinese website!