React.js Portalı

Öğeleri kendi DOM ağacının dışında oluşturmanın büyüsü

React.js'de Işınlanma

React'in, çocuklarını uygulamanızın içinde tamamen farklı bir yere monte edebilen “Portal” adlı özel ve çok güçlü bir bileşen sağladığını biliyor muydunuz? Değilse, yeni bir şeyler öğrenmenin zamanı geldi!

Bir React.js Portalının anatomisi

İşte React.js'deki Portal bileşeninin daha önce nasıl çalıştığına dair hızlı bir genel bakış.

  • Kodunuzun bir yerinde, Portal'ın alt öğelerini barındıracak bir öğe monte ediyorsunuz.
  • Sonra bu öğeye bir referans alırsınız
  • Uygulamanızda başka bir yerde, Portal bileşenini monte eder ve ana bilgisayar öğesinden alınan referansı iletirsiniz.
  • Artık Portalın içine monte edilen her şey, aslında ilk adımdan ana bilgisayara monte edilecektir.

Neler olup bittiğini daha iyi anlamak için Portal işlevselliğini göstermek için aşağıdaki basit görselleştirmeleri oluşturdum.

Image ee9c2dac28e7

Image 70ff8978589d

Image 886ed0a34985

Bu görüntülere dayanarak, aşağıdaki grafikler aynı işlemi gösterir, ancak bu sefer basitleştirilmiş kod örnekleri ile.

Image dd655b015a22

Image ab94e9940e3a

Portal, başlangıçta düşündüğünüzden bile daha güçlüdür. Hatta birden çok Portaldan birden çok çocuğu aynı hedef öğeye dönüştürmeye izin verir. Portalların montaj sırası, ana bilgisayardaki öğelerin sırasını da tanımlar.

Image de39ae9a02a2

Image b12fdf680f24

Işınlanan tüm çocukları içerecek olan ana bilgisayar öğesine yapılan referansı paylaşmak da çok kolaydır. Resmi belgeler, document.getElementById'nin kullanımını açıklar, ancak React.js'nin useRef-hook'unu da kullanabilirsiniz. Aşağıdaki kod örneği, şimdiye kadar açıklanan her şeyi gösteren basit bir uygulamayı göstermektedir.

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

Portal bileşeni daha basit kodlamayı nasıl sağlar?

Muhtemelen React.js Portalı için en yaygın kullanım durumu, bir Modal bileşeninin uygulanmasıdır. Hedefi uygulamanızın ağacının kökünde tanımlayabilir ve Portal bileşenini kullanarak her yerden, tüm içeriğin üzerinde güvenilir bir şekilde kayan bir modal monte edebilirsiniz.

Aslında uyguladığım başka bir kullanım durumu, bir sekme kabının kullanılmasıdır. Bir sekme kapsayıcı, hem bir sekme öğesinin hem de sekme seçildiğinde oluşturulacak içeriği gerektirdiğinden, biri sekme satırı için diğeri seçilen içerik için olmak üzere iki ana bilgisayar tanımlarım.

Ardından, sekme öğesi ve seçilen içerik için her biri bir portal kullanan bir dizi bileşen monte ediyorum. Bu, iş mantığını gerçekten ait olduğu yere - her bir ayrı bileşene - yerleştirmeme izin veriyor.

Image 2761da74cf8c

Image e7810bb469d2

Portal bileşeni için kesinlikle daha da ilginç kullanım durumları vardır. Sağladığını düşündüğüm en büyük avantaj, iş mantığının, çocukları daha sonra farklı yerlere monte edilen tek bir bileşende sıkı bir şekilde bağlanmasıdır. Bu model, büyük bir esneklik ve özelleştirme sağlar, ancak kod tabanınızda görünümlerin gerçekte nasıl ilişkili olduğu konusunda kafa karışıklığına yol açabilir.

Lütfen ayrıca React.js Portalları ile ilgili tüm ayrıntılar için resmi belgelere bakın.