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.
Ezekre a képekre építve az alábbi grafika ugyanazt a folyamatot mutatja, de ezúttal egyszerűsített kódpéldákkal.
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.
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.
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.