首頁 > web前端 > js教程 > 主體

使用虛擬 DOM 和引用進行高效 DOM 操作

WBOY
發布: 2024-07-29 17:10:06
原創
470 人瀏覽過

Efficient DOM Manipulation with the Virtual DOM and Refs
快速回應的網站的秘密
有沒有想過為什麼您最喜歡的網站如此快速且反應迅速?這一切都歸結為他們如何處理 DOM 操作。文件物件模型 (DOM) 將您的網頁表示為結構化樹。傳統上,我們使用 getElementById 或 removeChild 等 JavaScript 方法來進行變更。但隨著網站變得越來越複雜,這些方法可能會減慢速度。 React 登場了,它的虛擬 DOM 改變了遊戲規則。

傳統 DOM 操作的挑戰
將 DOM 視為一棵擁有大量分支的大樹。每當您想要更改某些內容(例如更新十個清單中的第一項)時,您最終都會搖動整棵樹。這可能會減慢速度,尤其是當網頁變得更加複雜時。分支(元素)越多,保持一切順利運作就越困難。

React 的解決方案:虛擬 DOM
React 透過 Virtual DOM(HTML DOM 的輕量級副本)解決了這個問題。變更首先應用於虛擬 DOM,然後 React 有效地更新真實 DOM 以反映這些變更。這個過程稱為“協調”,可確保僅更新 DOM 的必要部分,從而顯著提高效能。

虛擬 DOM 的工作原理
當您在 React 中渲染 JSX 元素時,整個虛擬 DOM 都會更新。雖然這聽起來效率很低,但它比直接操作真實 DOM 更快。原因如下:React 在進行任何更新之前建立虛擬 DOM 的副本。然後,它使用稱為 Diffing 的程序將更新的 Virtual DOM 與此副本進行比較。這種比較可以識別已更改的特定元素,React 僅更新真實 DOM 中的那些元素。

底層:React 的 Diffing 演算法
React 的 Diffing 演算法是其高效 DOM 更新背後的秘密武器。該演算法比較虛擬 DOM 的兩個版本,並應用同步它們所需的最小更改集。
如果兩棵樹的根元素類型不同,React 將重建整個樹。例如,將

變更為 a 將導致 React 拆除並從頭開始重建樹。
<div>
  <Tree/>
</div>
<span>
  <Tree/>
</span>
登入後複製

由於根元素(div 和 span)不同,React 將重建整個樹。

相同的元素類型

<span id="span1" />
<span id="span2" />
登入後複製

這裡,React 只會更新 id 屬性,元素的其餘部分保持不變。

比較子元素

React 也最佳化了子元素的更新。考慮這些清單:

<ul>
  <li>Child1</li>
  <li>Child2</li>
</ul>
登入後複製
<ul>
  <li>Child1</li>
  <li>Child2</li>
  <li>Child3</li>
</ul>
登入後複製

React 將 Child3 視為新的並進行相應更新。但是,如果在開頭新增元素,React 可能會重建整個清單。這就是鑰匙發揮作用的地方。
按鍵在最佳化更新中的作用

鍵幫助 React 追蹤哪些元素已更改、新增或刪除。它們在兄弟姐妹中應該是唯一的,並且在渲染中應該是穩定的。

<ul>
  <li key="101">Child1</li>
  <li key="102">Child2</li>
</ul>
登入後複製
<ul>
  <li key="100">Child3</li>
  <li key="101">Child1</li>
  <li key="102">Child2</li>
</ul>
登入後複製

在此範例中,React 知道 Child3 是新的,並有效地更新清單而不重建它。

使用 Ref 操作 DOM
雖然 React 使用 Virtual DOM 優化 DOM 更新,但在某些情況下需要直接操作 DOM 元素,例如對焦輸入、捲動到特定元素或測量元素的尺寸。 React 為此提供了 useRef Hook。透過建立 ref 並透過 ref 屬性將其附加到 DOM 元素,您可以直接存取 DOM 節點。 useRef Hook 傳回具有目前屬性的對象,該屬性最初為 null,但在渲染後會被指派 DOM 節點。這允許您直接在元素上呼叫本機 DOM 方法,從而增強對特定互動的控制。例如,您可以使用 myRef.current.scrollIntoView() 將元素捲動到視圖中。

範例:變色 Div
讓我們創建一個有趣的範例來看看它的實際效果。我們將製作一個當您單擊按鈕時改變顏色的 div。我們將使用基於類別的元件和 ref 來直接操作 div 的樣式。

<div id="root"></div>
登入後複製
const root = ReactDOM.createRoot(document.getElementById('root'));

class ColorChanger extends React.Component {
  constructor(props) {
    super(props);
    this.divRef = React.createRef();
    this.colors = ['#FFCDD2', '#C8E6C9', '#BBDEFB', '#FFF9C4', '#D1C4E9'];
    this.state = { colorIndex: 0 };
    this.changeColor = this.changeColor.bind(this);
  }

  changeColor() {
    const nextColorIndex = (this.state.colorIndex + 1) % this.colors.length;
    this.setState({ colorIndex: nextColorIndex });
    this.divRef.current.style.backgroundColor = this.colors[nextColorIndex];
  }

  render() {
    return (
      <div className="container">
        <div
          ref={this.divRef}
          className="color-box"
          style={{
            backgroundColor: this.colors[this.state.colorIndex],
          }}
        ></div>
        <button onClick={this.changeColor}>Change Color</button>
      </div>
    );
  }
}

root.render(<ColorChanger />);
登入後複製

說明

建立根:React 應用程式的根是使用 ReactDOM.createRoot(document.getElementById('root')) 建立的。
ColorChanger 組件:
建構子:使用 React.createRef() 初始化 ref,設定顏色數組,並初始化狀態以追蹤顏色索引。
changeColor 方法:計算下一個顏色索引,更新狀態,並透過直接操作 DOM 來變更 div 的背景顏色。
渲染方法:渲染div和按鈕,將ref附加到div並將按鈕的onClick處理程序設定為changeColor。
渲染元件:ColorChanger 元件被渲染到根元素中。
結論
React 的 Virtual DOM 改變了 Web 開發的遊戲規則,讓我們的應用程式更有效率、更快回應。透過利用虛擬 DOM,React 確保僅更新 DOM 的必要部分,從而提高效能。了解 React 的 Diffing 演算法和鍵的工作原理可以幫助您創建更流暢、更快的 React 應用程式。當你需要精確控制時,React 的 refs 可以幫助你直接與 DOM 互動。擁抱 Virtual DOM 的強大功能,將您的 Web 開發技能提升到新的水平!

以上是使用虛擬 DOM 和引用進行高效 DOM 操作的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板