React.js portál

Az elemek megjelenítésének varázsa a saját DOM-fán kívül

Teleportálás a React.js -ban

Tudta, hogy a React egy különleges és nagyon hatékony „Portal” nevű összetevőt kínál, amely gyermekeit az alkalmazáson belül egy teljesen más helyre szerelheti fel? Ha nem, akkor itt az ideje valami újat tanulni!

A React.js portál anatómiája

Íme egy gyors áttekintés arról, hogyan működik korábban a React.js portálkomponense.

  • Valahol a kódban rögzít egy elemet, amely a portál gyermekeit fogja fogadni
  • Ekkor kap egy hivatkozást erre az elemre
  • Valahol máshol az alkalmazásban telepíti a Portal-összetevőt, és átadja a gazdaelemtől kapott hivatkozást
  • Minden, ami most a Portálon belül van felszerelve, az első lépésben valójában a gazdagépben lesz felszerelve

Annak érdekében, hogy jobban megértsük, mi történik, a következő egyszerű vizualizációkat hoztam létre a portál működésének illusztrálására.

Image ee9c2dac28e7

Image 70ff8978589d

Image 886ed0a34985

Ezekre a képekre építve az alábbi grafika ugyanazt a folyamatot mutatja, de ezúttal egyszerűsített kódpéldákkal.

Image dd655b015a22

Image ab94e9940e3a

A Portál még erősebb, mint azt elsőre gondolná. Még azt is lehetővé teszi, hogy több gyermeket több portálról ugyanahhoz a célelemhez tegyen. A portálok felszerelési sorrendje meghatározza a hoszt elemeinek sorrendjét is.

Image de39ae9a02a2

Image b12fdf680f24

A hivatkozás megosztása a gazdaelemre, amely tartalmazza az összes teleportált gyermeket, szintén nagyon egyszerű. A hivatalos dokumentáció leírja a document.getElementById használatát, de használhatja a React.js useRef-hook használatát is. Az alábbi kódpélda egy egyszerű megvalósítást mutat be, amely az eddig leírtakat mutatja.

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

//
// Link to sandbox:
// 👉 https://codesandbox.io/s/react-16-8-0-forked-d8lm1?file=/src/index.js:0-1067
//

// A simple demonstration of the React-Portal
// w/ multiple portals for the same target.
function App() {
  const ref = useRef(null);
  const [isRefReady, setIsRefReady] = useState(false);

  // Run one more render to actually
  // show the content of our portal.
  // This is necessary, as the setter
  // for the 'ref' alone won't trigger
  // a render.
  useEffect(() => {
    setIsRefReady(Boolean(ref));
  }, []);

  return (
    <div>
      <div>
        {/* The 'target' aka host for our portals. */}
        <header ref={ref} style={{display: "flex", gap: 8 }} />
        <hr/>
      </div>
      <h1>
        Debug
      </h1>
      {isRefReady && createPortal(<button>one</button>, ref.current)}
      {isRefReady && createPortal(<button>two</button>, ref.current)}
      <div>
        {isRefReady && createPortal(<button>three</button>, ref.current)}
      </div>
    </div>
  );
}

ReactDOM.render(<App />, document.querySelector("#root"));

Hogyan teszi lehetővé a Portal-komponens az egyszerűbb kódolást

Valószínűleg a React.js portál leggyakoribb használati módja egy modális összetevő megvalósítása. Egyszerűen definiálhatja a célt az alkalmazás fájának gyökerében, és a Portal-komponens segítségével egy modalt csatlakoztathat mindenhonnan, megbízhatóan lebegve minden tartalom felett.

Egy másik felhasználási eset, amelyet ténylegesen megvalósítottam, a tabulátor használata. Mivel a lapok tárolójához mind a lapelem, mind a tartalom megjelenítése szükséges a lap kiválasztásakor, egyszerűen két gazdagépet definiálok, az egyiket a tabulátor sorhoz, a másikat a kiválasztott tartalomhoz.

Ezután csak egy sor összetevőt telepítek, amelyek mindegyike portált használ a tab-elemhez, valamint a kiválasztott tartalomhoz. Ez lehetővé teszi számomra, hogy az üzleti logikát oda helyezzem, ahol valójában van - minden egyes összetevőben.

Image 2761da74cf8c

Image e7810bb469d2

A Portal-összetevőnek minden bizonnyal vannak még érdekesebb felhasználási esetei. A legnagyobb előny szerintem, hogy lehetővé teszi az üzleti logika szoros összekapcsolását egyetlen összetevőben, amelynek gyermekeit különböző helyekre szerelik fel. Ez a minta nagy rugalmasságot és testreszabást tesz lehetővé, de zavart okozhat a kódbázisban a nézetek tényleges összefüggésében.

Kérjük, tekintse meg a React.js portálokkal kapcsolatos minden részletet a hivatalos dokumentációban is.