Как быстро приступить к работе с VUE3.0: Приступая к изучению
React 18, представлена новая концепция — transition
, которая включает в себя новый API — startTransition
и два новых перехватчика — useTransition
и usedeferredValue
. Эта статья начинается отсюда. Используйте введение для ранних пользователей.
1. Обзор
Эта статья разделена на четыре части:
tansition
,startTransition
useTransition
,useDeferredValue
2. Первоначальное намерение перехода,
transtion
напрямую переводится как过渡
. По сути, tansition为了解决渲染并发问题所提出
. В React, как только состояние компонента изменится и запустится повторный рендеринг, рендеринг невозможно остановить. Страница не может продолжать реагировать на действия пользователя, пока компонент не будет повторно отображен.
По этой причине обновления в реакции 18 можно разделить на следующие две категории:
紧急更新
: операции обновления, на которые пользователи ожидают немедленного ответа, например щелчки мыши или ввод с клавиатуры.过渡更新
: некоторые операции обновления с приемлемой задержкой, такие как запрос, рекомендации по поиску, отображение результатов поиска и т. д.// Обновляем startTransition(()=> { после того, как startTransiton пометил его для перехода // Несрочным обновлениям будет понижен приоритет, а выполнение setQueryValue(inputValue) будет отложено. }) // Если он не отмечен, setInputValue(inputValue) будет выполнено немедленно.
Обновление, отмеченное startTrionstion
в реакции 18, является переходным обновлением (приоритет выполнения снижается. В это время реакция будет задерживать выполнение внутреннего состояния). обновление в соответствии с внутренним механизмом планирования.
Разработчики, находящиеся в стадии разработки, могут решать, какие обновления помечаются как события перехода с помощью перехватчиков перехода. После того, как он отмечен, он представляет собой выполнение с низким приоритетом, то есть React знает, что обновление состояния может быть задержано.通过区分更新优先级
события с высоким приоритетом могут оставаться отзывчивыми,提高用户交互体验,保持页面响应
.
3. startTransiton
Введение в использование startTransiton
const handleClick = () => { // пакет startTransition помечен как обновление с низким приоритетом startTransition(()=> { setQueryValue (входное значение) }) // Если он не отмечен, setInputValue(inputValue) будет выполнен немедленно }
Во-первых, давайте представим простейший startTransition.
Путем демонстрации и сравнения
это симуляция сценария отображения результатов поиска после ввода символов. Подделывая большое количество результатов поиска, моделируется ситуация. который склонен к замерзанию.
Пробуем непрерывно вводить 123, отслеживать изменение value
поля поиска (срочное обновление) и изменение значения поиска searchVal
(обновление перехода) и выводить на панель управления.
импортировать React, { useEffect, useState, startTransition } из «реагировать»; импортировать './App.css' const SearchResult = (реквизит) => { const resultList = props.query ? Array.from({ длина: 10000 }, (_, индекс) => ({ идентификатор: индекс, ключевое слово: `${props.query} -- результаты поиска${index}`, }))): []; return resultList.map(({ id, ключевое слово }) => ( <li key={id}>{keyword}</li> )) } const App = () => { const [тип, setTpye] = useState(1) const [значение, setValue] = useState(''); const [searchVal, setSearchVal] = useState('-'); useEffect(() => { // Отслеживание изменений значения поиска console.log('Ответ на обновление значения поиска++++++' + searchVal + '++++++++++++') }, [searchVal]) useEffect(() => { console.log('Ответ на обновление значения поля ввода -----' + значение + '-------------') если (тип === 1) { setSearchVal(значение || '-') } если (тип === 2) { startTransition(() => { setSearchVal(значение || '-') }) } }, [значение, тип]); возвращаться ( <div className='Приложение'> <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> <ул> <SearchResult query={searchVal}></SearchResult> </ul> </div> ); };
В обычном режиме
如图所示:
непрерывно вводится 123 символа. При вводе первого символа значение поиска немедленно реагирует, и рендеринг списка начинается немедленно, в результате чего поле ввода зависает и перестает отвечать на ввод пользователя. продолжайте отвечать до завершения рендеринга.
После использования startTransition
如图所示:
При непрерывном вводе символов 123 поле ввода продолжает отвечать, а ответ на значение поиска задерживается, чтобы обеспечить обратную связь со страницей. Оно не начинает реагировать на значение поиска до конца ввода, обеспечивая рендеринг. результаты поиска и поддержание отзывчивости страницы.
4. useTransiton
Введение в использование
useTransiton import { useTransiton } from 'react' const [isPending, startTransition] = useTransiton({timeoutMs: 2000}) // Например, в состоянии ожидания вы можете отобразить Spinner { isPending ? < Spinner /> : null }
startTransition
— это функция, которая принимает обратный вызов и используется для информирования React о состоянии, которое необходимо отложить.isPending
— это логическое значение, которое позволяет реакции сообщить нам, следует ли ждать завершения перехода.useTransition
принимает значение отложенного ответа с помощью timeoutMs
. Если он не завершен в течение заданного timeoutMs, это приведет к принудительному обновлению состояния в функции обратного вызова startTransition
.Простой анализ useTransiton
Мы понимаем useTransition
через псевдокод.
функция useTransition(){ const [isPending, setPending] = mountState(false); const start = (обратный вызов)=>{ setPending (истина); // Scheduler.unstable_next В режиме перехода функция обратного вызова выполнения планирования с низким приоритетом // может снизить приоритет обновлений. Если обновление, инициированное обратным вызовом, имеет более низкий приоритет, // Будет установлено обновление с высоким приоритетом, или, когда текущая транзакция занята, ее применение будет запланировано на следующий период простоя. Scheduler.unstable_next(() => { const prevTransition = ReactCurrentBatchConfig.transition; ReactCurrentBatchConfig.transition = 1; пытаться { setPending (ложь); //Выполняем функцию обратного вызова callback(); } окончательно { ReactCurrentBatchConfig.transition = prevTransition; } }) } возврат [isPending, начало]; }
Во время выполнения startTransition
setPending сработает дважды: один раз перед transition=1
и один раз после. setPending(true)
при вызове startTransition
, а задача перехода transiton
обновляет setPending(false)
при выполнении функции обратного вызова внутри startTransition
. React может точно определить время перехода ожидания на основе изменений в ожидающем значении и использовать его, чтобы определить, превышен ли timeoutMs
(если таковой имеется) для принудительного обновления.
5. useDeferredValue
Введение в использование useDeferredValue
const [value, setValue] = useState('') // Значение defferedValue задерживается после обновления состояния const deferredValue = useDeferredValue(value, {timeoutMs: 2000})
timeoutMs
.一段逻辑
, а useDeferred генерирует一个新状态
.Использование useDeferredValue
import React, { useEffect, useState, useTransition, useDeferredValue } из «реагировать»; импортировать './App.css' const SearchResult = (реквизит) => { const resultList = props.query ? Array.from({ длина: 10000 }, (_, индекс) => ({ идентификатор: индекс, ключевое слово: `${props.query} -- результаты поиска${index}`, }))): []; return resultList.map(({ id, ключевое слово }) => ( <li key={id}>{keyword}</li> )) } const App = () => { const [значение, setValue] = useState(''); const searchValue = useDeferredValue (значение, {timeoutMs: 2000}); useEffect(() => { console.log('Ответ на значение поля ввода --------' + значение + '---------------') }, [ценить]) useEffect(() => { // Отслеживание изменений значения поиска console.log('Обновить ответ на значение поиска++++++' + searchValue + '++++++++++++') }, [searchValue]) возвращаться ( <div className='Приложение'> <input value={value} onChange={e => setValue(e.target.value)} /> <div className={`type_button type_button_checked`}>useDeferredValue</div> <ул> <SearchResult query={searchValue}></SearchResult> </ul> </div> ); };
Простой анализ useDeferredValue
Мы понимаем useDeferredValue
через псевдокод.
функция useDeferredValue(значение){ const [prevValue, setValue] = updateState (значение); updateEffect(() => { // Обновляем значение через режим перехода в useEffect. Scheduler.unstable_next(() => { const prevTransition = ReactCurrentBatchConfig.transition; ReactCurrentBatchConfig.transition = 1; пытаться { setValue (значение); } окончательно { ReactCurrentBatchConfig.transition = prevTransition; } }) }, [ценить]); вернуть предыдущее значение; }
useDeferredValue
прослушивает изменения входящего значения с помощью useEffect, а затем выполняет изменение значения с помощью задачи перехода. Это保证defrredValue的更新滞后于setState
и соответствует принципу переходного обновления, поскольку оно выполняется через механизм планирования перехода.