vue中nextTick函數(shù)和react類似實現(xiàn)代碼
Vue 3
基本用法:
import { nextTick } from 'vue'; // 全局調(diào)用 nextTick(() => { // 在下一個 DOM 更新循環(huán)后執(zhí)行的代碼 }); // 在組件內(nèi)部調(diào)用 setup() { async function handleUpdate() { // 修改數(shù)據(jù)... await nextTick(); // 在數(shù)據(jù)引發(fā)的 DOM 更新完成后執(zhí)行的代碼 } }
nextTick
函數(shù)現(xiàn)在作為vue
包的一個導出成員,需要顯式導入后使用。- 在組件的
setup
函數(shù)或其它上下文中,可以使用await nextTick()
的形式來等待 DOM 更新完成。
作用:
延遲執(zhí)行:確?;卣{(diào)函數(shù)在當前操作引發(fā)的 DOM 更新完成后執(zhí)行。這對于依賴于更新后 DOM 狀態(tài)的操作(如計算元素尺寸、位置,或進行額外的 DOM 操作)至關(guān)重要。
異步更新策略:
Vue 3 仍然遵循異步更新策略,即當組件狀態(tài)發(fā)生變化時,Vue 不會立即更新 DOM,而是將這些更新任務放入一個隊列中。在同一個事件循環(huán)中發(fā)生的多個狀態(tài)變更會被合并,然后在下一個事件循環(huán)的“微任務”階段一次性更新 DOM。這樣可以避免不必要的 DOM 操作,提高性能。
使用場景:
- 訪問更新后的 DOM:在修改數(shù)據(jù)后,如果需要基于更新后的 DOM 結(jié)構(gòu)或樣式執(zhí)行操作(如獲取元素尺寸、設置焦點等),應將這些操作放在 nextTick 回調(diào)中。
- 解決依賴更新順序的問題:有時需要確保某個操作在另一個操作引發(fā)的 DOM 更新之后執(zhí)行,例如在插入一個新的元素后立即滾動到該元素的位置。通過 nextTick 可以確保正確的執(zhí)行順序。
- 協(xié)調(diào)異步操作:在進行異步操作(如網(wǎng)絡請求)后需要更新界面時,可以在異步回調(diào)中使用 nextTick 確保 DOM 更新發(fā)生在數(shù)據(jù)變更之后。
實現(xiàn)原理:
Vue 3 中的 nextTick
主要通過 Promise 實現(xiàn)異步調(diào)度,返回一個 Promise 對象。當 DOM 更新完成后,Promise 被 resolve,從而觸發(fā) await nextTick()
后面的代碼執(zhí)行。Vue 3 也繼續(xù)支持回調(diào)函數(shù)形式的用法,但推薦使用 await
語句以獲得更好的代碼可讀性和錯誤處理能力。
react
在 React 中,雖然沒有直接提供名為 nextTick
的函數(shù),但其設計理念和異步更新機制與 Vue.js 中的 nextTick
概念類似。React 也采用了異步批量更新策略,即當組件狀態(tài)(state
或 props
)發(fā)生變化時,React 不會立即重新渲染組件和更新 DOM,而是將這些更新操作放入一個隊列中。當事件循環(huán)回到瀏覽器主線程時,React 會批量處理這些更新,一次性重新渲染受影響的組件并更新真實的 DOM。
如果你在 React 中需要實現(xiàn)類似 Vue.js nextTick
的效果,即在組件更新和 DOM 渲染完成后執(zhí)行某個操作,可以利用以下幾種方法:
1. 使用 useEffect
Hook:
import { useState, useEffect } from 'react'; function MyComponent() { const [value, setValue] = useState(0); useEffect(() => { // 此處的代碼會在 DOM 更新后執(zhí)行 // 適用于對 DOM 或全局狀態(tài)有依賴的操作 console.log('DOM 更新已完成,可以在這里操作'); }, [value]); // 依賴項 `value` 改變時觸發(fā)此 effect return ( <div> <p>You clicked {value} times</p> <button onClick={() => setValue(value + 1)}>Click me</button> </div> ); }
在上述代碼中,useEffect
Hook 的第二個參數(shù)(依賴數(shù)組)包含了 value
。當 value
變化時,React 會重新渲染組件,并在 DOM 更新后執(zhí)行 useEffect
內(nèi)部的回調(diào)函數(shù)。這樣就可以確保在 DOM 真實更新后再進行相關(guān)操作。
2. 使用 ReactDOM.flushSync
(僅限特殊場景):
import ReactDOM from 'react-dom'; function MyComponent() { const [value, setValue] = useState(0); function handleClick() { // 強制同步更新 DOM ReactDOM.flushSync(() => { setValue(value + 1); }); // 此處的代碼緊接著同步更新之后執(zhí)行 console.log('DOM 已經(jīng)同步更新'); } return ( <div> <p>You clicked {value} times</p> <button onClick={handleClick}>Click me</button> </div> ); }
ReactDOM.flushSync
是一個低級別的 API,用于強制同步執(zhí)行 React 更新。在極少數(shù)需要立即看到更新結(jié)果且不能等待下一次事件循環(huán)的場景下(如處理計時器的精確性問題),可以使用此方法。不過,由于同步更新可能會阻塞用戶界面,通常不建議常規(guī)使用,而是優(yōu)先考慮使用 useEffect
。
3. 使用 requestAnimationFrame
或 setTimeout(fn, 0)
:
function MyComponent() { const [value, setValue] = useState(0); function handleClick() { setValue(value + 1); requestAnimationFrame(() => { // 此處的代碼會在下一次重繪前執(zhí)行 console.log('DOM 大概率已經(jīng)更新'); }); } return ( <div> <p>You clicked {value} times</p> <button onClick={handleClick}>Click me</button> </div> ); }
或者:
function MyComponent() { const [value, setValue] = useState(0); function handleClick() { setValue(value + 1); setTimeout(() => { // 此處的代碼會在下一次事件循環(huán)中執(zhí)行 console.log('DOM 大概率已經(jīng)更新'); }, 0); } return ( <div> <p>You clicked {value} times</p> <button onClick={handleClick}>Click me</button> </div> ); }
requestAnimationFrame
和 setTimeout(fn, 0)
都可以將代碼推遲到下一次瀏覽器重繪或事件循環(huán)中執(zhí)行,此時 DOM 更新大概率已完成。雖然不如 useEffect
那樣精確地綁定到 React 更新周期,但對于大多數(shù)需要在 DOM 更新后執(zhí)行操作的場景來說,這兩種方法通常是足夠可靠的。
綜上所述,React 中沒有與 Vue.js 中 nextTick
函數(shù)同名的工具,但通過使用 useEffect
Hook、ReactDOM.flushSync
(特殊情況)、requestAnimationFrame
或 setTimeout(fn, 0)
,可以實現(xiàn)類似的在 DOM 更新后執(zhí)行操作的需求。在大多數(shù)情況下,useEffect
是首選解決方案,因為它與 React 的更新機制緊密集成,確保在恰當?shù)臅r機執(zhí)行回調(diào)。
相關(guān)文章
Vue中使用Echarts儀表盤展示實時數(shù)據(jù)的實現(xiàn)
這篇文章主要介紹了Vue中使用Echarts儀表盤展示實時數(shù)據(jù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11vue實現(xiàn)下拉多選、可搜索、全選功能(示例代碼)
本文介紹了如何在Vue中實現(xiàn)一個樹形結(jié)構(gòu)的下拉多選組件,支持任意一級選項的選擇,全選功能,以及搜索功能,通過在mounted生命周期中獲取數(shù)據(jù),并使用handleTree函數(shù)將接口返回的數(shù)據(jù)整理成樹形結(jié)構(gòu),實現(xiàn)了這一功能,感興趣的朋友一起看看吧2025-01-01