Portalo React.js

La magio bildigi elementojn ekster la propra DOM-arbo

Teletransportado en React.js

Ĉu vi scias, ke React provizas specialan kaj tre potencan eron nomatan "Portalo", kiu povas munti siajn infanojn en tute alia loko ene de via programo? Se ne, estas tempo lerni ion novan!

La anatomio de Portalo React.js

Jen rapida superrigardo pri kiel la Portalo-ero en React.js funkcias antaŭe.

  • Ie en via kodo, vi muntas elementon, kiu gastigos la infanojn de la Portalo
  • Tiam vi ricevas referencon al ĉi tiu elemento
  • Ie aliloke en via programo, vi tiam muntas la Portal-komponenton kaj preterpasas la referencon akiritan de la gastiga elemento
  • Ĉio nun muntita ene de la Portalo efektive estos muntita en la gastiganto ekde la unua paŝo

Por pli bone kompreni kio okazas, mi kreis la jenajn simplajn bildigojn por ilustri la Portal-funkciecon.

Image ee9c2dac28e7

Image 70ff8978589d

Image 886ed0a34985

Konstruante ĉi tiujn bildojn, la sekvaj grafikoj montras la saman procezon, sed ĉi-foje kun simpligitaj kodekzemploj.

Image dd655b015a22

Image ab94e9940e3a

La Portalo estas eĉ pli potenca ol vi povus pensi komence. Ĝi eĉ permesas redoni plurajn infanojn de pluraj Portaloj al la sama celelemento. La ordo de muntado de la portaloj ankaŭ difinas la ordon de la elementoj en la gastiganto.

Image de39ae9a02a2

Image b12fdf680f24

Dividi la referencon al la gastiga elemento, kiu enhavos ĉiujn teletransportitajn infanojn, estas ankaŭ tre facila. La oficiala dokumentaro priskribas la uzadon de document.getElementById, sed vi ankaŭ povas uzi React.js 'useRef-hook. La sekva kodekzemplo montras simplan efektivigon, kiu montras ĉion priskribitan ĝis nun.

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"));

Kiel la Portalo-komponanto ebligas pli simplan kodigon

Probable la plej ofta uzokazo por la React.js-Portalo estas la efektivigo de Modala komponanto. Vi povas simple difini la celon ĉe la radiko de la arbo de via programo kaj uzi la Portal-komponenton por munti modalon de ĉie, fidinde flosante super ĉia enhavo.

Alia uzokazo, kiun mi efektive efektivigis, estas la uzado de tabujo. Ĉar tabujo enhavas ambaŭ tabelilon mem kaj ankaŭ la enhavon por bildigi kiam la langeto estas elektita, mi simple difinas du gastigantojn, unu por la tab-vico kaj la alia por la elektita enhavo.

Tiam mi simple muntas aron da eroj, kiuj ĉiu uzas portalon por la tab-ero kaj ankaŭ elektitan enhavon. Ĉi tio permesas al mi meti la komercan logikon tie, kie ĝi efektive apartenas - en ĉiu aparta ero.

Image 2761da74cf8c

Image e7810bb469d2

Certe estas eĉ pli interesaj uzokazoj por la Portal-komponanto. La plej granda avantaĝo, kiun mi pensas, ke ĝi ebligas, estas la strikta kuniĝo de komerca logiko en unu sola ero, kies infanoj tiam muntiĝas en diversaj lokoj. Ĉi tiu ŝablono ebligas grandan flekseblecon kaj personigon, sed povas kaŭzi konfuzon en via kodbazo, kiel la vidpunktoj efektive rilatas.

Bonvolu ankaŭ rigardi la oficialan dokumentaron por ĉiuj detaloj pri React.js Portals.