كيفية البدء سريعًا باستخدام VUE3.0: عند الدخول لتعلم
React 18، تم تقديم مفهوم جديد - transition
، والذي يجلب واجهة برمجة تطبيقات جديدة - startTransition
وخطافين جديدين - useTransition
و usedeferredValue
. تبدأ هذه المقالة من هنا استخدم مقدمات المتبني المبكر.
1. نظرة عامة
تنقسم هذه المقالة إلى أربعة أجزاء:
tansition
،startTransition
useTransition
،useDeferredValue
2. النية الأصلية للانتقال،
تتم ترجمة transtion
مباشرة إلى过渡
.为了解决渲染并发问题所提出
. في 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} من 'react'; استيراد "./App.css" نتيجة البحث const = (الدعائم) => { const resultList =props.query Array.from({ الطول: 10000 }, (_, الفهرس) => ({؟ المعرف: الفهرس، الكلمة الرئيسية: `${props.query} -- نتائج البحث${index}`، })): []; إرجاع resultList.map(({ المعرف، الكلمة الأساسية }) => ( <li key={id}>{keyword}</li> )) } تطبيق ثابت = () => { const [نوع، setTpye] = useState(1) const [value, setValue] = useState(''); const [searchVal, setSearchVal] = useState('-'); استخدام التأثير (() => { // مراقبة تغييرات قيمة البحث console.log('الاستجابة لتحديث قيمة البحث++++++' + searchVal + '++++++++++++') }، [سيرتشفال]) استخدام التأثير (() => { console.log ("الاستجابة لتحديث قيمة مربع الإدخال -----" + value + "-------------") إذا (اكتب === 1) { setSearchVal(القيمة || '-') } إذا (اكتب === 2) { startTransition(() => { setSearchVal(القيمة || '-') }) } }، [القيمة، النوع])؛ يعود ( <div className='App'> <قيمة الإدخال={قيمة} onChange={e => setValue(e.target.value)} /> <div className={`type_button ${type === 1 ? 'type_button_checked' : ''}`} onClick={() => setTpye(1)}>عادي</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 مقدمة الاستخدام
استيراد { useTransiton} من 'react' const [isPending, startTransition] = useTransiton({timeoutMs: 2000}) // على سبيل المثال، في الحالة المعلقة، يمكنك عرض Spinner { isPending ? < Spinner /> : null }
startTransition
هي دالة تقبل رد الاتصال وتُستخدم لإعلام React بالحالة التي يجب تأخيرها.isPending
هو قيمة منطقية، وهي طريقة رد الفعل لإخبارنا ما إذا كنا سننتظر حتى يكتمل النقل.useTransition
قيمة الاستجابة المؤجلة باستخدام timeoutMs
. إذا لم يتم إكمالها خلال المهلة المحددة، فسوف يفرض تحديث الحالة في وظيفة رد الاتصال startTransition
.تحليل بسيط لـ useTransiton
نحن نفهم useTransition
من خلال الكود الزائف.
وظيفة UseTransition () { const [isPending, setPending] = mountState(false); بداية ثابتة = (رد الاتصال)=>{ setPending(true); //Scheduler.unstable_next من خلال وضع النقل، يمكن لوظيفة رد الاتصال لتنفيذ الجدولة ذات الأولوية المنخفضة // تقليل أولوية التحديثات. إذا كان التحديث الذي تم تشغيله في رد الاتصال له أولوية أقل، // سيتم تعيينه على تحديث ذي أولوية عالية، أو عندما تكون المعاملة الحالية مشغولة، ستتم جدولة تطبيقه في فترة الخمول التالية. جدولة.unstable_next(() => { const prevTransition = ReactCurrentBatchConfig.transition; ReactCurrentBatchConfig.transition = 1; يحاول { setPending(false); // تنفيذ وظيفة رد الاتصال callback(); } أخيراً { ReactCurrentBatchConfig.transition = prevTransition; } }) } العودة [في انتظار البدء]؛ }
أثناء تنفيذ startTransition
، سيتم تشغيل setPending مرتين، مرة قبل transition=1
ومرة بعده. setPending(true)
عند استدعاء startTransition
، وتقوم مهمة الانتقال transiton
بتحديث setPending(false)
عند تنفيذ وظيفة رد الاتصال داخل startTransition
. يمكن لـ React فهم وقت انتقال الانتظار بدقة استنادًا إلى التغييرات في القيمة المعلقة، واستخدام ذلك لتحديد ما إذا كان قد تم تجاوز timeoutMs
(إذا تم تمرير أي منها) لفرض التحديث.
5. useDeferredValue
useDeferredValue مقدمة لاستخدام
const [value, setValue] = useState('') // تم تأجيل قيمة deferedValue بعد تحديث الحالة const deferredValue = useDeferredValue(value, {timeoutMs: 2000})
timeoutMs
التأخير.一段逻辑
، بينما ينشئ useDeferred一个新状态
.استخدام useDeferredValue
import React, { useEffect, useState, useTransition, useDeferredValue } from 'react'; استيراد "./App.css" نتيجة البحث const = (الدعائم) => { const resultList =props.query Array.from({ الطول: 10000 }, (_, الفهرس) => ({؟ المعرف: الفهرس، الكلمة الرئيسية: `${props.query} -- نتائج البحث${index}`، })): []; إرجاع resultList.map(({ المعرف، الكلمة الأساسية }) => ( <li key={id}>{keyword}</li> )) } تطبيق ثابت = () => { const [value, setValue] = useState(''); const searchValue = useDeferredValue(value, { timeoutMs: 2000 }); استخدام التأثير (() => { console.log('الاستجابة لقيمة مربع الإدخال --------' + value + '---------------') }، [قيمة]) استخدام التأثير (() => { // مراقبة تغييرات قيمة البحث console.log('تحديث الاستجابة لقيمة البحث++++++' + searchValue + '++++++++++++') }، [قيمة البحث]) يعود ( <div className='App'> <قيمة الإدخال={قيمة} onChange={e => setValue(e.target.value)} /> <div className={`type_button type_button_checked`}>useDeferredValue</div> <ul> <SearchResult query={searchValue}></SearchResult> </ul> </div> ); };
تحليل بسيط لـ useDeferredValue
نحن نفهم useDeferredValue
من خلال الكود الزائف.
الدالة useDeferredValue(value){ const [prevValue, setValue] = updateState(value); تحديث التأثير (() => { // تحديث القيمة من خلال وضع الانتقال في useEffect. جدولة.unstable_next(() => { const prevTransition = ReactCurrentBatchConfig.transition; ReactCurrentBatchConfig.transition = 1; يحاول { setValue(value); } أخيراً { ReactCurrentBatchConfig.transition = prevTransition; } }) }، [قيمة])؛ إرجاع القيمة السابقة؛ }
يستمع useDeferredValue
إلى التغييرات في القيمة الواردة من خلال useEffect، ثم يقوم بإجراء تغيير القيمة من خلال مهمة النقل. وهذا保证defrredValue的更新滞后于setState
ويتوافق مع مبدأ التحديث الانتقالي لأنه يتم تنفيذه من خلال آلية جدولة النقل.