วิธีเริ่มต้นอย่างรวดเร็วด้วย VUE3.0: การเข้าสู่การเรียนรู้
React 18 มีการนำเสนอแนวคิดใหม่ - transition
ซึ่งนำ API ใหม่ - startTransition
และ hook ใหม่สองรายการ - useTransition
และ usedeferredValue
1. ภาพรวม
บทความนี้แบ่งออกเป็น 4 ส่วน ได้แก่
tansition
startTransition
useTransition
useDeferredValue
2 ความตั้งใจเดิมของ Transition
transtion
จะแปลโดยตรงว่า过渡
Tansition ถูก为了解决渲染并发问题所提出
ใน React เมื่อสถานะของส่วนประกอบเปลี่ยนแปลงและมีการทริกเกอร์การเรนเดอร์ซ้ำ จะไม่สามารถหยุดการเรนเดอร์ได้ เพจไม่สามารถตอบสนองต่อการโต้ตอบของผู้ใช้ต่อไปได้จนกว่าคอมโพเนนต์จะถูกเรนเดอร์อีกครั้ง
ด้วยเหตุนี้ การอัปเดตในปฏิกิริยา 18 จึงสามารถแบ่งออกเป็นสองประเภทดังต่อไปนี้:
紧急更新
: การดำเนินการอัปเดตที่ผู้ใช้คาดว่าจะตอบสนองทันที เช่น การคลิกเมาส์หรือการป้อนข้อมูลด้วยแป้นพิมพ์过渡更新
: การดำเนินการอัปเดตบางอย่างที่มีความล่าช้าที่ยอมรับได้ เช่น ข้อความค้นหา คำแนะนำการค้นหา การแสดงผลการค้นหา เป็นต้น// อัปเดต startTransition(()=> { หลังจากถูกทำเครื่องหมายโดย startTransiton เพื่อการเปลี่ยนแปลง // การอัปเดตที่ไม่เร่งด่วนจะถูกลดลำดับความสำคัญลง และการดำเนินการ setQueryValue(inputValue) จะล่าช้าออกไป - // หากไม่ได้ทำเครื่องหมายไว้ setInputValue(inputValue) จะถูกดำเนินการทันที
การอัปเดตที่ทำเครื่องหมายโดย startTrionstion
ในการตอบสนอง 18 ถือเป็นการอัปเดตเฉพาะกาล (ลำดับความสำคัญในการดำเนินการลดลง) ในเวลานี้ การตอบสนองจะทำให้การดำเนินการของสถานะภายในล่าช้า อัปเดตตามกลไกการกำหนดเวลาภายใน
นักพัฒนาที่อยู่ระหว่างการพัฒนาสามารถตัดสินใจได้ว่าการอัปเดตใดจะถูกทำเครื่องหมายเป็นเหตุการณ์การเปลี่ยนแปลงผ่าน hooks การเปลี่ยนแปลง เมื่อทำเครื่องหมายแล้ว จะแสดงถึงการดำเนินการที่มีลำดับความสำคัญต่ำ กล่าวคือ 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 = อุปกรณ์ประกอบฉาก.query ? Array.from({ ความยาว: 10,000 }, (_, ดัชนี) => ({ รหัส: ดัชนี คำหลัก: `${props.query} -- ผลการค้นหา${index}`, - return resultList.map(({ id, คำสำคัญ }) => ( <li key={id}>{keyword}</li> - - แอป const = () => { 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='แอป'> <ค่าอินพุต={value} 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)}>การขนส่ง</div> <ul> <SearchResult query={searchVal}></SearchResult> </ul> </div> - };
ในโหมดปกติ
如图所示:
ป้อนอักขระ 123 ตัวอย่างต่อเนื่อง เมื่อป้อนอักขระตัวแรก ค่าการค้นหาจะตอบสนองทันที และการเรนเดอร์รายการจะเริ่มต้นทันที ทำให้ช่องอินพุตค้างและหยุดตอบสนองต่ออินพุตของผู้ใช้ ตอบสนองต่อไปจนกว่าการเรนเดอร์จะเสร็จสิ้น
หลังจากใช้ startTransition
如图所示:
ป้อนอักขระ 123 อย่างต่อเนื่อง กล่องป้อนข้อมูลยังคงตอบสนอง และการตอบสนองต่อค่าการค้นหาจะล่าช้าเพื่อให้แน่ใจว่ามีการตอบรับหน้ากระดาษ ผลการค้นหาและการรักษาหน้าเว็บให้ตอบสนอง
4. useTransiton
useTransiton แนะนำการใช้งาน
นำเข้า { useTransiton } จาก 'react' const [isPending, startTransition] = useTransiton ({timeoutMs: 2000}) // ตัวอย่างเช่น ในสถานะรอดำเนินการ คุณสามารถแสดงสปินเนอร์ได้ { isPending ? < Spinner /> : null }
startTransition
เป็นฟังก์ชันที่ยอมรับการโทรกลับและใช้เพื่อแจ้ง React ถึงสถานะที่ต้องล่าช้าisPending
เป็นบูลีน ซึ่งเป็นวิธีโต้ตอบในการแจ้งให้เราทราบว่าจะรอให้การเปลี่ยนแปลงเสร็จสมบูรณ์หรือไม่useTransition
ยอมรับค่าของการตอบสนองล่าช้าด้วย timeoutMs
หากไม่เสร็จสิ้นภายใน timeoutMs ที่กำหนด ระบบจะบังคับให้อัปเดตสถานะในฟังก์ชันเรียกกลับ startTransition
การวิเคราะห์ useTransiton อย่างง่าย
เราเข้าใจ useTransition
ผ่านโค้ดเทียม
ฟังก์ชั่นการใช้งานการเปลี่ยนผ่าน () { const [isPending, setPending] = mountState (เท็จ); const start = (โทรกลับ)=>{ setPending(จริง); // Scheduler.unstable_next ผ่านโหมด Transiton ฟังก์ชันโทรกลับการดำเนินการจัดกำหนดการที่มีลำดับความสำคัญต่ำ // สามารถลดลำดับความสำคัญของการอัปเดตได้ หากการอัปเดตที่ทริกเกอร์ในการเรียกกลับมีลำดับความสำคัญต่ำกว่า // จะถูกตั้งค่าเป็นการอัปเดตที่มีลำดับความสำคัญสูง หรือเมื่อธุรกรรมปัจจุบันไม่ว่าง ก็จะถูกกำหนดให้นำไปใช้ในช่วงเวลาว่างถัดไป Scheduler.unstable_next(() => { const prevTransition = ReactCurrentBatchConfig.transition; ReactCurrentBatchConfig.transition = 1; พยายาม { setPending(เท็จ); //ดำเนินการฟังก์ชันโทรกลับ โทรกลับ(); } ในที่สุด { ReactCurrentBatchConfig.transition = การเปลี่ยนแปลงก่อนหน้า; - - - กลับ [อยู่ระหว่างดำเนินการ, เริ่มต้น]; }
ในระหว่างการดำเนินการ 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
นำเข้า React, { useEffect, useState, useTransition, useDeferredValue } จาก 'react'; นำเข้า './App.css' const SearchResult = (อุปกรณ์ประกอบฉาก) => { const resultList = อุปกรณ์ประกอบฉาก.query ? Array.from({ ความยาว: 10,000 }, (_, ดัชนี) => ({ รหัส: ดัชนี คำหลัก: `${props.query} -- ผลการค้นหา${index}`, - return resultList.map(({ id, คำสำคัญ }) => ( <li key={id}>{keyword}</li> - - แอป const = () => { const [ค่า, setValue] = useState(''); const searchValue = useDeferredValue (ค่า, { timeoutMs: 2000 }); useEffect(() => { console.log ('ตอบสนองต่อค่ากล่องอินพุต --------' + ค่า + '---------------') }, [ค่า]) useEffect(() => { // ตรวจสอบการเปลี่ยนแปลงค่าการค้นหา console.log ('อัปเดตการตอบสนองต่อค่าการค้นหา ++++++' + searchValue + '++++++++++++') }, [ค่าการค้นหา]) กลับ ( <div className='แอป'> <ค่าอินพุต={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
ผ่านโค้ดเทียม
ฟังก์ชั่น useDeferredValue (ค่า) { const [prevValue, setValue] = updateState (ค่า); อัพเดตเอฟเฟ็กต์(() => { // อัปเดตค่าผ่านโหมดการเปลี่ยนแปลงใน useEffect Scheduler.unstable_next(() => { const prevTransition = ReactCurrentBatchConfig.transition; ReactCurrentBatchConfig.transition = 1; พยายาม { setValue(ค่า); } ในที่สุด { ReactCurrentBatchConfig.transition = การเปลี่ยนแปลงก่อนหน้า; - - }, [ค่า]); กลับค่าก่อนหน้า; }
useDeferredValue
จะรับฟังการเปลี่ยนแปลงในค่าที่เข้ามาผ่าน useEffect จากนั้นจึงทำการเปลี่ยนแปลงค่าผ่านงานการเปลี่ยนแปลง保证defrredValue的更新滞后于setState
และสอดคล้องกับหลักการของการอัปเดตเฉพาะกาล เนื่องจากดำเนินการผ่านกลไกการกำหนดตารางเวลาการเปลี่ยนแปลง