بوابة React.js

سحر عرض العناصر خارج شجرة DOM الخاصة

النقل الآني في React.js

هل تعلم أن React يوفر مكونًا خاصًا وقويًا جدًا يسمى "Portal" يمكنه تثبيت عناصره في مكان مختلف تمامًا داخل تطبيقك؟ إذا لم يكن الأمر كذلك ، فقد حان الوقت لتعلم شيء جديد!

تشريح بوابة React.js

فيما يلي نظرة عامة سريعة على كيفية عمل مكون Portal في React.js من قبل.

  • في مكان ما في التعليمات البرمجية الخاصة بك ، تقوم بتركيب عنصر يستضيف أطفال البوابة
  • ثم تحصل على إشارة إلى هذا العنصر
  • في مكان آخر في التطبيق الخاص بك ، تقوم بعد ذلك بتركيب مكون Portal وتمرير المرجع الذي تم الحصول عليه من عنصر المضيف
  • كل شيء يتم تركيبه الآن داخل البوابة سيتم بالفعل تركيبه في المضيف من الخطوة الأولى

لفهم ما يجري بشكل أفضل ، قمت بإنشاء التصورات البسيطة التالية لتوضيح وظيفة البوابة.

Image ee9c2dac28e7

Image 70ff8978589d

Image 886ed0a34985

بناءً على هذه الصور ، تُظهر الرسومات التالية نفس العملية ، ولكن هذه المرة بأمثلة تعليمات برمجية مبسطة.

Image dd655b015a22

Image ab94e9940e3a

البوابة أقوى مما تعتقد في البداية. حتى أنه يسمح بتصيير العديد من الأطفال من بوابات متعددة إلى نفس العنصر الهدف. يحدد ترتيب تركيب البوابات أيضًا ترتيب العناصر في المضيف.

Image de39ae9a02a2

Image b12fdf680f24

من السهل جدًا أيضًا مشاركة الإشارة إلى العنصر المضيف الذي سيحتوي على جميع الأطفال المنقولين آنيًا. يصف التوثيق الرسمي استخدام document.getElementById ، ولكن يمكنك أيضًا استخدام استخدام React.js 'useRef-hook. يوضح مثال الكود التالي تنفيذًا بسيطًا يعرض كل ما تم وصفه حتى الآن.

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 تشفيرًا أبسط

من المحتمل أن تكون حالة الاستخدام الأكثر شيوعًا لبوابة React.js هي تنفيذ مكون شكلي. يمكنك ببساطة تحديد الهدف في جذر شجرة تطبيقك واستخدام مكون Portal لتركيب نموذج من كل مكان ، بحيث يطفو بشكل موثوق فوق كل المحتوى.

حالة استخدام أخرى قمت بتنفيذها بالفعل هي استخدام حاوية علامة التبويب. نظرًا لأن حاوية علامة التبويب تتطلب كلاً من عنصر علامة التبويب نفسه بالإضافة إلى المحتوى المطلوب عرضه عند تحديد علامة التبويب ، فأنا ببساطة أحدد مضيفين ، أحدهما لصف علامة التبويب والآخر للمحتوى المحدد.

ثم أقوم فقط بتركيب مجموعة من المكونات التي يستخدم كل منها مدخلًا لعنصر علامة التبويب بالإضافة إلى المحتوى المحدد. هذا يسمح لي بوضع منطق الأعمال حيث ينتمي بالفعل - في كل مكون منفصل.

Image 2761da74cf8c

Image e7810bb469d2

هناك بالتأكيد حالات استخدام أكثر إثارة للاهتمام لمكون Portal. أكبر ميزة أعتقد أنها تتيحها هي الاقتران الوثيق لمنطق الأعمال في مكون واحد ، والذي يتم بعد ذلك تركيب أبنائه في أماكن مختلفة. يتيح هذا النمط قدرًا كبيرًا من المرونة والتخصيص ، ولكن يمكن أن يؤدي إلى حدوث ارتباك في قاعدة التعليمات البرمجية الخاصة بك حول كيفية ارتباط طرق العرض بالفعل.

يرجى أيضًا إلقاء نظرة على الوثائق الرسمية لجميع التفاصيل المتعلقة ببوابات React.js.