欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React實現(xiàn)浮層組件的思路與方法詳解

 更新時間:2024年02月06日 15:42:35   作者:lecepin  
React?浮層組件(也稱為彈出組件或彈窗組件)通常是指在用戶界面上浮動顯示的組件,本文主要介紹了浮層組件的實現(xiàn)方法,感興趣的小伙伴可以了解下

React 浮層組件(也稱為彈出組件或彈窗組件)通常是指在用戶界面上浮動顯示的組件,它們脫離常規(guī)的文檔流,并且可以在用戶進行某些操作時出現(xiàn)在頁面的最上層。React 浮層組件可以用于創(chuàng)建模態(tài)框(Modal)、下拉菜單(Dropdown)、工具提示(Tooltip)、側(cè)邊欄(Sidebar)或任何其他需要動態(tài)顯示和隱藏且通常位置固定或絕對定位的內(nèi)容。

React 浮層組件的特點包括:

  • 層級管理:浮層組件通常具有較高的z-index值,使得它們能夠顯示在其他內(nèi)容之上。
  • 動態(tài)性:它們通常是響應(yīng)用戶交互(如點擊按鈕或鼠標懸停)而顯示的,并且可以通過用戶交互(如點擊遮罩層或按下 Escape 鍵)來關(guān)閉。
  • 定位:浮層組件可以根據(jù)觸發(fā)它們的元素(如按鈕或鏈接)的位置動態(tài)定位。
  • 獨立渲染:為了避免 CSS 布局的限制(如overflow或父元素的z-index),浮層組件通常使用 React 的ReactDOM.createPortal方法渲染到 DOM 樹的其他位置,比如直接渲染到document.body下。
  • 可訪問性(Accessibility):良好的浮層組件應(yīng)該考慮到可訪問性,比如焦點管理、鍵盤導(dǎo)航和屏幕閱讀器的支持。

1. 實現(xiàn)簡單的 Tootip

Tootip 就是簡單的文字提示氣泡框。

簡單實現(xiàn):

import React, { useState, useRef } from "react";

const Tooltip = ({ children, text }) => {
  const [visible, setVisible] = useState(false);
  const tooltipRef = useRef();

  const showTooltip = () => setVisible(true);
  const hideTooltip = () => setVisible(false);

  // 獲取觸發(fā)元素的位置,以便正確定位Tooltip
  const computePosition = () => {
    if (tooltipRef.current) {
      const { top, height } = tooltipRef.current.getBoundingClientRect();
      return {
        top: top + height + window.scrollY,
        left: 0 + window.scrollX,
      };
    }

    return { top: 0, left: 0 };
  };

  const tooltipStyle = {
    position: "absolute",
    border: "1px solid #ccc",
    backgroundColor: "white",
    padding: "5px",
    zIndex: 1000,
    ...computePosition(), // 計算位置并應(yīng)用樣式
    display: visible ? "block" : "none", // 控制顯示與隱藏
  };

  return (
    <div
      style={{ position: "relative", display: "inline-block" }}
      ref={tooltipRef}
    >
      <div
        style={tooltipStyle}
        onMouseEnter={showTooltip}
        onMouseLeave={hideTooltip}
      >
        {text}
      </div>
      <div onMouseEnter={showTooltip} onMouseLeave={hideTooltip}>
        {children}
      </div>
    </div>
  );
};

// 使用Tooltip的組件
const App = () => {
  return (
    <div>
      <p>
        Hover over the word{" "}
        <Tooltip text="A helpful tooltip.">"tooltip"</Tooltip> to see the
        tooltip.
      </p>
    </div>
  );
};

2. 存在問題

上面的 Tooltip 實現(xiàn)確實可能帶來一些問題。以下是一些主要考慮點:

影響原布局

  • 由于 Tooltip 采用絕對定位,它可能會覆蓋頁面上的其他元素而不是占據(jù)自己的空間。這可能導(dǎo)致頁面元素的重疊,尤其是當 Tooltip 很大的時候。
  • 如果 Tooltip 的觸發(fā)元素沒有設(shè)置合適的定位上下文(如 position: relative),Tooltip 可能會相對于錯誤的父元素定位,出現(xiàn)在頁面意外的位置。

可能被隱藏

  • 如果 Tooltip 的父元素設(shè)置了 overflow: hidden 或者 clip-path 屬性,這可能會導(dǎo)致 Tooltip 被裁剪或完全隱藏。
  • 當 Tooltip 出現(xiàn)在視口邊緣附近時,部分 Tooltip 可能會位于視口外,從而導(dǎo)致內(nèi)容不完全可見。

性能問題

  • Tooltip 的位置計算涉及 DOM 的讀取操作(如 getBoundingClientRect),這可能會導(dǎo)致回流(reflow)和重繪(repaint),尤其是在大型應(yīng)用中或在頻繁更新的情況下。
  • 鼠標事件的頻繁觸發(fā)(如 onMouseEnter 和 onMouseLeave)可能導(dǎo)致 Tooltip 的頻繁顯示和隱藏,進而引發(fā)性能問題。

可訪問性問題

  • 不使用 createPortal 的 Tooltip 可能不會管理焦點,這會影響鍵盤用戶和屏幕閱讀器用戶的體驗。
  • 如果 Tooltip 中的內(nèi)容對用戶理解頁面很重要,但僅通過鼠標懸停來顯示,鍵盤用戶可能無法訪問這些信息。

屏幕適配問題

  • Tooltip 在移動設(shè)備上可能表現(xiàn)不佳,因為移動設(shè)備通常沒有懸停狀態(tài),可能需要其他機制來觸發(fā) Tooltip。
  • 在響應(yīng)式設(shè)計中,Tooltip 可能需要不同的樣式或定位策略以適應(yīng)不同屏幕尺寸。

復(fù)雜度增加

當頁面中有許多 Tooltip 時,管理它們的位置和可見性狀態(tài)可能會變得復(fù)雜。

為了解決這些問題,您可能需要進一步優(yōu)化 Tooltip 組件,例如:

  • 使用 debounce 或 throttle 函數(shù)來減少位置計算的頻率,優(yōu)化性能。
  • 添加額外的邏輯來確保 Tooltip 在視口內(nèi)完全可見,例如通過調(diào)整位置或改變 Tooltip 出現(xiàn)的方向。
  • 通過添加適合鍵盤導(dǎo)航的交互來提高可訪問性,例如使 Tooltip 在獲取焦點時顯示。
  • 為移動設(shè)備實現(xiàn)不同的交互模式,或者完全避免在小屏幕上使用 Tooltip。

盡管有這些潛在的問題,但在某些情況下,這種不使用 createPortal 的實現(xiàn)方式可能足夠滿足簡單的需求。對于更復(fù)雜的情況,則可能需要考慮更高級的解決方案,例如使用 React.createPortal 或第三方庫,這些庫已經(jīng)解決了上述問題。

3. createPortal

ReactDOM.createPortal 是 React 提供的一個 API,它允許你把子節(jié)點渲染到存在于父組件之外的 DOM 節(jié)點上。這個方法的簽名如下:

ReactDOM.createPortal(child, container);

其中 child 是任何可以渲染的 React 子元素,例如一個元素、字符串或碎片(fragment),而 container 是一個 DOM 元素。

createPortal 的主要用處包括:

事件冒泡:使用 createPortal 渲染的子組件會在 DOM 樹上處于不同的位置,但從 React 的角度來看,它仍然存在于 React 組件樹中原來的位置,這意味著事件可以正常冒泡到 React 父組件,盡管這些元素在 DOM 層級結(jié)構(gòu)中并不直接相連。

避免 CSS 約束:在某些情況下,你可能不希望子組件受到父組件 CSS 的影響,例如在一個設(shè)置了overflow: hiddenz-index的父元素內(nèi)部渲染一個模態(tài)對話框(modal)或工具提示(tooltip)。通過使用 createPortal,模態(tài)或工具提示可以渲染到 DOM 樹中的其他位置,例如直接渲染到document.body下,從而避免了這些 CSS 約束。

視覺上的“脫離”:當你需要組件在視覺上位于頁面層次結(jié)構(gòu)之外時(如模態(tài)框、通知、懸浮卡片等),createPortal 提供了一種將組件結(jié)構(gòu)上與視覺結(jié)構(gòu)分離的方法。這可能是因為這些組件需要在頁面上占據(jù)最頂層,以避免被其他元素遮擋。

createPortal 注意事項

假設(shè)你指的是 "reactportal" 中可能遇到的問題,那么在使用 React 的 createPortal API 時,以下是一些可能遇到的典型問題和挑戰(zhàn):

  • 事件冒泡:使用 createPortal 創(chuàng)建的 React 元素雖然在 DOM 樹中是在不同位置,但它們在 React 組件樹中仍然保持原位置。因此,事件冒泡將不按照 DOM 結(jié)構(gòu)進行,而是沿著 React 組件樹向上冒泡。這可能導(dǎo)致一些意料之外的行為,尤其是在復(fù)雜的事件處理邏輯中。
  • 樣式隔離:當彈出的內(nèi)容移動到 DOM 樹的其他部分時,可能會丟失某些由上層組件提供的 CSS 樣式。你可能需要額外處理以確保彈出內(nèi)容的樣式與預(yù)期一致。
  • 上下文不一致:雖然 createPortal 允許在 React 組件樹中保留上下文,但如果你在 DOM 樹中的其他位置使用 Portal,與 Portal 交互的 DOM 元素可能不會有相同的上下文(例如,React 的 Context API)。
  • 輔助技術(shù)的支持:移動到 DOM 樹其他位置的內(nèi)容可能會影響輔助技術(shù)(如屏幕閱讀器)對頁面的解讀,因為這些內(nèi)容在語義結(jié)構(gòu)上可能被解讀為與它們在屏幕上的視覺位置不一致。
  • 性能考量:如果你頻繁創(chuàng)建和銷毀 Portal,或者 Portal 中包含大量動態(tài)內(nèi)容,這可能會影響應(yīng)用的性能。
  • 服務(wù)端渲染(SSR)兼容性:在服務(wù)端渲染環(huán)境下,由于沒有 document.body,使用 createPortal 可能需要額外的處理來確保代碼的兼容性。
  • 滾動和定位問題:如果 Portal 內(nèi)容需要基于觸發(fā)元素的位置進行定位,頁面滾動或窗口大小變化時可能需要更新位置,這可能會需要額外的事件監(jiān)聽和狀態(tài)管理。
  • 嵌套 Portal:在 Portal 內(nèi)部創(chuàng)建另一個 Portal 可能會導(dǎo)致一些復(fù)雜的層級問題,特別是在處理事件和樣式時。
  • 可訪問性(a11y):創(chuàng)建的 Portal 內(nèi)容可能會打亂鍵盤導(dǎo)航順序,或者改變焦點管理的預(yù)期行為。你可能需要手動管理焦點以確保良好的可訪問性。

為了解決這些問題,你可能需要實施一些策略,比如在樣式上使用更高的特異性,使用輔助技術(shù)友好的方法來管理焦點,或者確保上下文在 Portal 內(nèi)部和外部保持一致。此外,對于性能和兼容性問題,可能需要一些額外的優(yōu)化和測試。

4. cloneElement

React 的 cloneElement 函數(shù)允許你克隆一個 React 元素,并傳入新的 props、ref。這個函數(shù)的簽名如下:

React.cloneElement(element, [props], [...children]);
  • element 是你想要克隆的 React 元素。
  • props 是一個對象,其中包含了你希望在克隆的元素上設(shè)置或覆蓋的新屬性。
  • children 是任意數(shù)量的子元素,用于替換克隆元素的子元素。

cloneElement 主要用于以下幾種場景:

  • 屬性增強:當你需要增強一個元素的功能而又不想顯式創(chuàng)建一個新的組件時,你可以使用 cloneElement 來添加或修改屬性。例如,你可以為一個元素添加額外的 onMouseEnteronClick 等事件處理器。
  • 條件渲染:你可以對子組件進行有條件的修改,例如在特定情況下為子組件添加附加的 props 或樣式。
  • 引用保持cloneElement 在克隆時保持子元素類型的不變和 key 的不變,這有助于保持組件的狀態(tài)和避免不必要的卸載和重新掛載。
  • 與高階組件(Higher-Order Components, HOCs)結(jié)合:在開發(fā)高階組件時,cloneElement 可以用來包裹傳入的子組件,并為其注入需要的 props。
  • 與 React 的 Context 結(jié)合:有時候你可能需要在組件樹中深處的組件接收到來自頂層的 props,為了避免明確地傳遞這些 props,你可以使用 cloneElement 結(jié)合 Context API 來靈活地為深層組件注入所需的數(shù)據(jù)。

以下是一個使用 cloneElement 來增強子組件 onMouseEnter 事件的例子:

import React, { cloneElement } from "react";

class EnhancedComponent extends React.Component {
  handleMouseEnter = () => {
    // 提供額外的 onMouseEnter 行為
    console.log("Mouse entered!");
  };

  render() {
    const { children } = this.props;

    // 假設(shè)我們只處理一個子元素的情況
    const child = React.Children.only(children);

    // 克隆子元素并注入新的 onMouseEnter 處理器
    const enhancedChild = cloneElement(child, {
      onMouseEnter: this.handleMouseEnter,
    });

    return enhancedChild;
  }
}

export default EnhancedComponent;

在這個例子中,EnhancedComponent 接收一個單一的子組件,并使用 cloneElement 對其進行克隆,添加一個新的 onMouseEnter 事件處理器。如果原始子組件已經(jīng)有 onMouseEnter 處理器,這個新的處理器會被合并,兩個處理器都會被執(zhí)行。

總之,cloneElement 在不同的用例中都很有用,尤其是當你想要微調(diào)元素的屬性或行為而又不想創(chuàng)建全新的組件時。然而,過度使用 cloneElement 可能使組件變得難以理解和維護,因此應(yīng)該謹慎使用。

5. 重寫 Tootip

使用 cloneElement 和 createPortal 來實現(xiàn)一個 Tooltip 組件,可以將 Tooltip 的內(nèi)容渲染到頁面的頂級位置,同時注入事件處理器到觸發(fā)元素。這樣的實現(xiàn)可以解決上文提到的一些問題,例如避免因為 overflow 或 z-index 造成的渲染問題。

以下是一個簡單的函數(shù)式組件模式的 Tooltip 實現(xiàn):

import React, { useState, useRef, useEffect } from "react";
import ReactDOM from "react-dom";

const Tooltip = ({ children, content }) => {
  const [show, setShow] = useState(false);
  const [position, setPosition] = useState({ top: 0, left: 0 });
  const childRef = useRef(null);

  const handleMouseEnter = () => {
    if (childRef.current) {
      const rect = childRef.current.getBoundingClientRect();
      setPosition({
        top: rect.bottom + window.scrollY,
        left: rect.left + window.scrollX,
      });
    }
    setShow(true);
  };

  const handleMouseLeave = () => {
    setShow(false);
  };

  useEffect(() => {
    window.addEventListener("scroll", handleMouseLeave);
    return () => {
      window.removeEventListener("scroll", handleMouseLeave);
    };
  }, []);

  const tooltip =
    show &&
    ReactDOM.createPortal(
      <div
        style={{
          position: "absolute",
          top: position.top,
          left: position.left,
          zIndex: 1000,
          backgroundColor: "#fff",
          border: "1px solid #ddd",
          padding: "5px",
          borderRadius: "3px",
          boxShadow: "0 2px 5px rgba(0,0,0,0.2)",
        }}
      >
        {content}
      </div>,
      document.body
    );

  const clonedChild = React.cloneElement(children, {
    onMouseEnter: handleMouseEnter,
    onMouseLeave: handleMouseLeave,
    ref: childRef,
  });

  return (
    <>
      {clonedChild}
      {tooltip}
    </>
  );
};

// 使用Tooltip的組件
const App = () => {
  return (
    <div style={{ marginTop: "100px", marginLeft: "100px" }}>
      <Tooltip content="This is a tooltip!">
        <button>Hover over me!</button>
      </Tooltip>
    </div>
  );
};

export default App;

在這個例子中,Tooltip 組件接受一個 children 屬性和一個 content 屬性。children 是觸發(fā) Tooltip 的元素,content 是顯示在 Tooltip 中的內(nèi)容。

使用 cloneElement,我們?yōu)?nbsp;children 元素克隆一個新版本并添加了 onMouseEnter 和 onMouseLeave 事件處理器,用于控制 Tooltip 的顯示和隱藏。

我們使用 createPortal 將 Tooltip 內(nèi)容渲染到 document.body 中,這樣 Tooltip 就能夠避開任何本地 CSS 的限制。show 狀態(tài)控制 Tooltip 的顯示,position 狀態(tài)用于計算 Tooltip 應(yīng)該出現(xiàn)在頁面上的位置。

通過 useEffect,我們添加了對 scroll 事件的監(jiān)聽來在頁面滾動時隱藏 Tooltip,防止 Tooltip 位置不正確。

這樣,你就得到了一個使用 cloneElement 和 createPortal 實現(xiàn)的 Tooltip 組件,它可以在不影響頁面布局和樣式的情況下工作,并且能夠在頁面上的任何位置正確地顯示 Tooltip。

5.1 同步元素滾動

上面的代碼示例中,Tooltip 在觸發(fā)元素的 onMouseEnter 事件處理器中計算其顯示位置,并在 onMouseLeave 或窗口的 scroll 事件中被隱藏。這意味著一旦 Tooltip 顯示出來,如果用戶滾動頁面,Tooltip 會保持在首次顯示時計算出的固定位置,而不會跟隨觸發(fā)元素移動。

如果要實現(xiàn) Tooltip 位置與觸發(fā)元素同步滾動的效果,需要動態(tài)更新 Tooltip 的位置,以響應(yīng)頁面的滾動事件。這可以通過在 useEffect 鉤子中添加對滾動事件的監(jiān)聽來實現(xiàn)。在滾動事件的回調(diào)中,我們可以重新計算 Tooltip 的位置,使其與觸發(fā)元素保持同步。

以下是更新后的代碼示例,實現(xiàn)了 Tooltip 與觸發(fā)元素同步滾動的效果:

import React, { useState, useRef, useEffect } from "react";
import ReactDOM from "react-dom";

const Tooltip = ({ children, content }) => {
  const [show, setShow] = useState(false);
  const childRef = useRef(null);

  const updatePosition = () => {
    if (childRef.current) {
      const rect = childRef.current.getBoundingClientRect();
      return {
        top: rect.bottom + window.scrollY,
        left: rect.left + window.scrollX,
      };
    }
  };

  const [position, setPosition] = useState({ top: 0, left: 0 });

  const handleMouseEnter = () => {
    setPosition(updatePosition());
    setShow(true);
  };

  const handleMouseLeave = () => {
    setShow(false);
  };

  useEffect(() => {
    const handleScroll = () => {
      if (show) {
        setPosition(updatePosition());
      }
    };

    window.addEventListener("scroll", handleScroll);

    // 清理函數(shù)
    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, [show]); // 依賴于 `show`,僅當 Tooltip 顯示時添加事件監(jiān)聽

  const tooltip =
    show &&
    ReactDOM.createPortal(
      <div
        style={{
          position: "absolute",
          top: position.top,
          left: position.left,
          zIndex: 1000,
          backgroundColor: "#fff",
          border: "1px solid #ddd",
          padding: "5px",
          borderRadius: "3px",
          boxShadow: "0 2px 5px rgba(0,0,0,0.2)",
          // 添加 transition 效果使位置更新更平滑
          transition: "top 0.3s, left 0.3s",
        }}
      >
        {content}
      </div>,
      document.body
    );

  const clonedChild = React.cloneElement(children, {
    onMouseEnter: handleMouseEnter,
    onMouseLeave: handleMouseLeave,
    ref: childRef,
  });

  return (
    <>
      {clonedChild}
      {tooltip}
    </>
  );
};

// 使用Tooltip的組件
const App = () => {
  return (
    <div style={{ marginTop: "100px", marginLeft: "100px" }}>
      <Tooltip content="This is a tooltip!">
        <button>Hover over me!</button>
      </Tooltip>
    </div>
  );
};

export default App;

在這個更新的實現(xiàn)中,添加了 updatePosition 函數(shù),它負責(zé)根據(jù)當前觸發(fā)元素的位置來更新 Tooltip 的位置。在 useEffect 中注冊了頁面滾動的事件監(jiān)聽器 handleScroll,它會在頁面滾動時調(diào)用 updatePosition 來更新 Tooltip 的位置。監(jiān)聽器僅在 Tooltip 顯示時進行注冊,從而避免不必要的事件監(jiān)聽和執(zhí)行。

綜上所述,更新后的代碼使得 Tooltip 能夠在頁面滾動時跟隨觸發(fā)元素移動,從而解決了位置同步的問題。

5.2 防止 cloneElement 注入破壞

在使用 cloneElement 對子組件增強或注入新的屬性和事件處理器時,需要特別注意不要覆蓋子組件原有的屬性和事件處理器。為了避免這種覆蓋,可將原有的屬性和處理器與新的屬性和處理器合并。

下面是一個示例,它展示了如何使用 cloneElement 來增強子組件的 onMouseEnter 和 onMouseLeave 事件處理器,同時保留原有的事件處理器:

import React, { useState, useRef } from "react";
import ReactDOM from "react-dom";

const Tooltip = ({ children, content }) => {
  const [show, setShow] = useState(false);
  const childRef = useRef(null);

  const handleMouseEnter = (originalOnMouseEnter) => (event) => {
    // 如果子組件有自己的 onMouseEnter 事件處理器,先調(diào)用它
    if (originalOnMouseEnter) {
      originalOnMouseEnter(event);
    }
    // 然后執(zhí)行 Tooltip 特定的邏輯
    setShow(true);
  };

  const handleMouseLeave = (originalOnMouseLeave) => (event) => {
    // 如果子組件有自己的 onMouseLeave 事件處理器,先調(diào)用它
    if (originalOnMouseLeave) {
      originalOnMouseLeave(event);
    }
    // 然后執(zhí)行 Tooltip 特定的邏輯
    setShow(false);
  };

  const tooltipElement =
    show &&
    ReactDOM.createPortal(
      <div
        style={
          {
            /* Tooltip樣式 */
          }
        }
      >
        {content}
      </div>,
      document.body
    );

  // 克隆子組件,合并事件處理器
  const clonedChild = React.cloneElement(children, {
    ref: childRef,
    onMouseEnter: handleMouseEnter(children.props.onMouseEnter),
    onMouseLeave: handleMouseLeave(children.props.onMouseLeave),
  });

  return (
    <>
      {clonedChild}
      {tooltipElement}
    </>
  );
};

// 使用Tooltip的組件
const App = () => {
  const handleButtonMouseEnter = () => {
    console.log("Button's original onMouseEnter called");
  };

  const handleButtonMouseLeave = () => {
    console.log("Button's original onMouseLeave called");
  };

  return (
    <div style={{ marginTop: "100px", marginLeft: "100px" }}>
      <Tooltip content="This is a tooltip!">
        <button
          onMouseEnter={handleButtonMouseEnter}
          onMouseLeave={handleButtonMouseLeave}
        >
          Hover over me!
        </button>
      </Tooltip>
    </div>
  );
};

export default App;

在 Tooltip 組件中,我們?yōu)?nbsp;handleMouseEnter 和 handleMouseLeave 方法分別傳入了子組件原有的 onMouseEnter 和 onMouseLeave 事件處理器。然后在這些方法的閉包中,如果存在原有的事件處理器,我們先調(diào)用這些原有的事件處理器,接著執(zhí)行 Tooltip 的邏輯。這樣一來,我們就可以確保子組件的原有行為不會被 Tooltip 組件的行為覆蓋。

如此,cloneElement 能夠安全地用于增強子組件,而不會破壞子組件的預(yù)期行為。

6. 其他優(yōu)化

在實現(xiàn) React 組件時,尤其是在開發(fā)像 Tooltip 這樣可能大量使用的組件時,考慮性能優(yōu)化是非常重要的。下面是一些性能優(yōu)化的建議:

避免不必要的重新渲染

  • 使用 React.memo 來包裹函數(shù)組件,避免在 props 沒有改變的情況下發(fā)生不必要的渲染。
  • 確保你的組件盡可能地只在必要時更新。比如,如果 Tooltip 組件的狀態(tài)沒有改變,就沒有必要更新 DOM。

減少重計算

  • 通過緩存計算結(jié)果(如使用 useMemo 鉤子),減少 Tooltip 位置計算的次數(shù)。
  • 使用 throttle 或 debounce 函數(shù)限制事件處理器的調(diào)用頻率,尤其是對于像 resize 和 scroll 這樣可能頻繁觸發(fā)的事件。

優(yōu)化事件處理器

  • 確保添加的事件監(jiān)聽器(比如滾動監(jiān)聽器)在組件卸載時被移除,以避免內(nèi)存泄漏。
  • 如果有可能,使用事件委托來減少事件監(jiān)聽器的數(shù)量。

使用 shouldComponentUpdate 或 React.PureComponent:

  • 對于類組件,可以通過實現(xiàn) shouldComponentUpdate 方法來避免不必要的更新。
  • 如果你的類組件擁有不可變的 props 和 state,可以考慮使用 React.PureComponent,它自動為 shouldComponentUpdate 提供了一個淺比較實現(xiàn)。

減少 DOM 操作

對于使用 createPortal 的組件,盡可能減少 DOM 節(jié)點的插入和移除操作??梢钥紤]在應(yīng)用的頂層預(yù)先定義好掛載點,而不是動態(tài)創(chuàng)建和銷毀。

利用 CSS 動畫代替 JS 動畫

當可能時,使用 CSS 動畫和過渡效果,因為它們可以利用 GPU 加速,而 JS 動畫可能會觸發(fā)更多的重繪和回流。

使用懶加載

如果 Tooltip 內(nèi)容很大或包含圖片等資源,可以考慮使用懶加載技術(shù),只有當 Tooltip 顯示時才加載內(nèi)容。

避免內(nèi)聯(lián)函數(shù)定義

避免在渲染方法中定義內(nèi)聯(lián)函數(shù),因為這將在每次渲染時創(chuàng)建新的函數(shù)實例,這可能會導(dǎo)致子組件的不必要重渲染。

分離組件

將大型組件拆分成更小、更容易管理的子組件,這樣可以更精細地控制渲染行為。

使用 key 屬性

當渲染列表或集合時,確保每個元素都有一個獨特的 key 屬性,這可以幫助 React 在更新過程中識別和重用 DOM 節(jié)點。

通過實施上述優(yōu)化策略,你可以提高組件的性能,特別是在渲染大量 Tooltip 或在滾動等高頻事件觸發(fā)時。性能優(yōu)化是一個持續(xù)的過程,始終需要根據(jù)實際場景和應(yīng)用需求來評估和調(diào)整。

以上就是React實現(xiàn)浮層組件的思路與方法詳解的詳細內(nèi)容,更多關(guān)于React浮層組件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React項目配置prettier和eslint的方法

    React項目配置prettier和eslint的方法

    這篇文章主要介紹了React項目配置prettier和eslint的相關(guān)知識,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • react配置webpack-bundle-analyzer項目優(yōu)化踩坑記錄

    react配置webpack-bundle-analyzer項目優(yōu)化踩坑記錄

    這篇文章主要介紹了react配置webpack-bundle-analyzer項目優(yōu)化踩坑記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • React中state屬性案例詳解

    React中state屬性案例詳解

    在React中,state 是一個用于存儲組件內(nèi)部數(shù)據(jù)的特殊對象,每個React組件都可以包含自己的state,我們往往是通過修改state的值來驅(qū)動React重新渲染組件,這篇文章主要介紹了React中state屬性,需要的朋友可以參考下
    2023-11-11
  • 詳解關(guān)于react-redux中的connect用法介紹及原理解析

    詳解關(guān)于react-redux中的connect用法介紹及原理解析

    本篇文章主要介紹了詳解關(guān)于react-redux中的connect用法介紹及原理解析,非常具有實用價值,需要的朋友可以參考下
    2017-09-09
  • React?中?memo?useMemo?useCallback?到底該怎么用

    React?中?memo?useMemo?useCallback?到底該怎么用

    在React函數(shù)組件中,當組件中的props發(fā)生變化時,默認情況下整個組件都會重新渲染。換句話說,如果組件中的任何值更新,整個組件將重新渲染,包括沒有更改values/props的函數(shù)/組件。在react中,我們可以通過memo,useMemo以及useCallback來防止子組件的rerender
    2022-10-10
  • React跨端動態(tài)化之從JS引擎到RN落地詳解

    React跨端動態(tài)化之從JS引擎到RN落地詳解

    這篇文章主要為大家介紹了React跨端動態(tài)化之從JS引擎到RN落地,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • React前端開發(fā)createElement源碼解讀

    React前端開發(fā)createElement源碼解讀

    這篇文章主要為大家介紹了React前端開發(fā)createElement源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • 淺談React?Refs?使用場景及核心要點

    淺談React?Refs?使用場景及核心要點

    本文主要介紹了React?Refs?使用場景及核心要點,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • webpack4 + react 搭建多頁面應(yīng)用示例

    webpack4 + react 搭建多頁面應(yīng)用示例

    這篇文章主要介紹了webpack4 + react 搭建多頁面應(yīng)用示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • react父組件調(diào)用子組件的方式匯總

    react父組件調(diào)用子組件的方式匯總

    在react中常用props實現(xiàn)子組件數(shù)據(jù)到父組件的傳遞,但是父組件調(diào)用子組件的功能卻不常用,下面這篇文章主要給大家介紹了關(guān)于react父組件調(diào)用子組件的相關(guān)資料,需要的朋友可以參考下
    2022-08-08

最新評論