תבנית פשוטה לחיבור React ו Rails עם Webpacker

20/09/2019

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

1. איך זה עובד

ל React On Rails יש Helper שנקרא react_component אותו אנחנו יכולים לרשום בתוך View כדי לרנדר פקד ריאקט לתוך ה View. ה Helper מקבל את שם הפקד ואוביקט עבור ה Properties שלו, ולכן כותבים את זה בערך כך:

<%= react_component("HelloWorld", props: @hello_world_props) %>

המשתנה @hello_world_props הגיע מה Controller, והפקד מוגדר ב JavaScript בתוך קובץ jsx.

מסתבר שממש קל לייצר מבנה דומה גם בלי React On Rails. הנה מה שנעשה:

  1. נגדיר תגית Script שתקבל בתור data-attributes את שם הפקד ואת ה props שלו.

  2. נהפוך את המידע מה Controller ל JSON לבד באמצעות json_escape ו to_json בשביל להעביר את ה props כ Data Attribute.

  3. נכתוב קצת קוד JavaScript שימשוך את הפרטים מתגית הסקריפט ויבנה את הפקד.

2. ה View

התחנה הראשונה שלנו היא ה View והפעם אנחנו עובדים בלי ה Helper של React On Rails לכן אסתפק ב script tag רגיל. הקוד כדי לשתול פקד ריאקט יראה כך:

<%=
  javascript_pack_tag 'react_component',
                      'data-page': 'hello_world',
                      'data-props': json_escape({ text: @text }.to_json)
%>

השם react_component הוא שם קובץ הסקריפט שאני טוען, המאפיין data-page קובע איזה פקד ספציפי להציג והמאפיין data-props קובע את ה Properties שעוברים לפקד.

3. הקובץ react_component.jsx

בשביל ש javascript_pack_tag יעבוד אנחנו צריכים קובץ בשם react_component. קובץ זה הוא שיקרא את מאפייני ה data כדי ליצור את הפקד. העבודה בגדול תהיה:

  1. חפש את תגית הסקריפט שבגללה הגענו לקובץ

  2. שלוף ממנה את המאפיין data-page כדי לגלות איזה פקד להציג

  3. שלוף ממנה את המאפיין data-props כדי לגלות מה ה Properties שצריך להעביר לו.

  4. טען את הפקד עם import.

  5. צור אלמנט והצג אותו על העמוד.

בקוד זה נראה כך:

import React from 'react'
import ReactDOM from 'react-dom'

// Find the script tag that got us here
const el = document.currentScript;

// When the content is loaded
document.addEventListener('DOMContentLoaded', async () => {
  // parse data-props attribute as JSON
  const props = JSON.parse(el.dataset.props);

  // load the component from data-page
  const page  = el.dataset.page;
  const { default: component } = await import(`./${page}`);

  // render the component with the provided props
  ReactDOM.render(
    React.createElement(component, props, null),
    document.body.appendChild(document.createElement('div')),
  )
});

4. קובץ הפקד עצמו

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

הנה פקד ה hello world שדיברתי עליו שמציג את הטקסט שקיבל מה View:

import React from 'react';

export default function HelloWorld(props) {
    return (
        <h1>{props.text}</h1>
    );
}