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



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


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


من السهل جدًا أيضًا مشاركة الإشارة إلى العنصر المضيف الذي سيحتوي على جميع الأطفال المنقولين آنيًا. يصف التوثيق الرسمي استخدام 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 لتركيب نموذج من كل مكان ، بحيث يطفو بشكل موثوق فوق كل المحتوى.
حالة استخدام أخرى قمت بتنفيذها بالفعل هي استخدام حاوية علامة التبويب. نظرًا لأن حاوية علامة التبويب تتطلب كلاً من عنصر علامة التبويب نفسه بالإضافة إلى المحتوى المطلوب عرضه عند تحديد علامة التبويب ، فأنا ببساطة أحدد مضيفين ، أحدهما لصف علامة التبويب والآخر للمحتوى المحدد.
ثم أقوم فقط بتركيب مجموعة من المكونات التي يستخدم كل منها مدخلًا لعنصر علامة التبويب بالإضافة إلى المحتوى المحدد. هذا يسمح لي بوضع منطق الأعمال حيث ينتمي بالفعل - في كل مكون منفصل.


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