פורטל React.js

הקסם של עיבוד אלמנטים מחוץ לעץ DOM עצמו

טלפורטציה ב- React.js

האם ידעת ש- React מספקת רכיב מיוחד ורב עוצמה בשם "פורטל" שיכול להרכיב את ילדיו במקום אחר לגמרי בתוך האפליקציה שלך? אם לא, הגיע הזמן ללמוד משהו חדש!

האנטומיה של פורטל React.js

להלן סקירה מהירה של אופן רכיב הפורטל ב- React.js.

  • איפשהו בקוד שלך, אתה מחבר אלמנט שיארח את ילדי הפורטל
  • לאחר מכן תקבל התייחסות לאלמנט זה
  • במקום אחר באפליקציה שלך, לאחר מכן תעלה את רכיב הפורטל ותעביר את ההפניה המתקבלת מהרכיב המארח
  • כל מה שעכשיו מותקן בתוך הפורטל יותקן במארח כבר מהשלב הראשון

כדי להבין טוב יותר מה קורה, יצרתי את ההדמיות הפשוטות הבאות להמחשת הפונקציונליות של הפורטל.

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

כיצד רכיב הפורטל מאפשר קידוד פשוט יותר

כנראה מקרה השימוש הנפוץ ביותר בפורטל React.js הוא יישום רכיב Modal. אתה יכול פשוט להגדיר את היעד בשורש העץ של האפליקציה שלך ולהשתמש ברכיב הפורטל כדי להעלות מודל מכל מקום, צף באופן אמין מעל כל התוכן.

מקרה שימוש אחר שיישמתי בפועל הוא השימוש בכלי טאב. מכיוון שמיכל כרטיסיות דורש הן פריט לשונית והן התוכן כדי לעבד כאשר הכרטיסייה נבחרת, אני פשוט מגדיר שני מארחים, אחד לשורת הכרטיסיות והשני עבור התוכן שנבחר.

אחר כך אני פשוט מכין מערך של רכיבים שכל אחד מהם משתמש בפורטל עבור פריט הכרטיסיה כמו גם תוכן שנבחר. זה מאפשר לי למקם את ההיגיון העסקי היכן שהוא שייך בפועל - בכל רכיב נפרד.

Image 2761da74cf8c

Image e7810bb469d2

בהחלט ישנם מקרי שימוש מעניינים עוד יותר עבור רכיב הפורטל. היתרון הגדול ביותר שלדעתי הוא מאפשר הוא צימוד הדוק של ההיגיון העסקי ברכיב אחד, שילדיו ירכזו אז במקומות שונים. דפוס זה מאפשר גמישות והתאמה אישית רבה, אך יכול להוביל לבלבול בבסיס הקוד שלך כיצד התצוגות קשורות למעשה.

אנא עיין גם בתיעוד הרשמי לכל הפרטים הנוגעים לפורטלים של React.js.