לדלג לתוכן

קומפוננטות ופרופס בריאקט מוסברים

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

מה זה בעצם קומפוננטה

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

function Greeting() {
  return <h1>שלום עולם</h1>;
}

כדי להשתמש בקומפוננטה, קוראים לה כמו תגית HTML, לא כמו פונקציה רגילה:

function App() {
  return (
    <div>
      <Greeting />
    </div>
  );
}

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

props - איך מעבירים מידע לקומפוננטה

קומפוננטה בפני עצמה שימושית, אבל קומפוננטה שאפשר להתאים אישית שימושית הרבה יותר. props (מקוצר מ-properties) הם הדרך להעביר נתונים מקומפוננטת אב לקומפוננטת בת, בדיוק כמו שמעבירים ארגומנטים לפונקציה.

function Greeting({ name }) {
  return <h1>שלום {name}</h1>;
}

function App() {
  return (
    <div>
      <Greeting name="דנה" />
      <Greeting name="יוסי" />
    </div>
  );
}

כל קריאה ל-Greeting מקבלת name שונה, ומציגה תוכן שונה בהתאם. ה-props מגיעים תמיד כאובייקט יחיד, ולכן כמעט תמיד רואים דסטרקצ'רינג בפרמטר של הקומפוננטה, כמו { name } בדוגמה למעלה, במקום לקבל props שלם ולגשת ל-props.name.

props יכולים להיות כל דבר - לא רק מחרוזות

props יכולים להיות מספרים, בוליאנים, אובייקטים, מערכים, ואפילו פונקציות:

function ProductCard({ name, price, inStock, onAddToCart }) {
  return (
    <div>
      <h2>{name}</h2>
      <p>{price} ש"ח</p>
      {inStock ? (
        <button onClick={onAddToCart}>הוסף לעגלה</button>
      ) : (
        <p>אזל מהמלאי</p>
      )}
    </div>
  );
}

function App() {
  function handleAddToCart() {
    console.log("נוסף לעגלה");
  }

  return (
    <ProductCard
      name="כיסא משרדי"
      price={450}
      inStock={true}
      onAddToCart={handleAddToCart}
    />
  );
}

שימו לב - ערכים שהם לא מחרוזות עוברים בסוגריים מסולסלים ({450}, {true}), בעוד מחרוזות פשוטות אפשר להעביר במרכאות רגילות ("כיסא משרדי").

children - prop מיוחד להעברת תוכן פנימי

יש prop אחד שמתנהג קצת אחרת מהשאר - children, שמייצג את כל מה שנכתב בין תגית הפתיחה לתגית הסגירה של הקומפוננטה:

function Card({ children }) {
  return <div className="card">{children}</div>;
}

function App() {
  return (
    <Card>
      <h2>כותרת</h2>
      <p>תוכן כלשהו בתוך הכרטיס</p>
    </Card>
  );
}

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

props הם קריאה בלבד - אף פעם לא לשנות אותם

חוק ברזל בריאקט - קומפוננטה אף פעם לא משנה את ה-props שהיא קיבלה. ה-props מגיעים "מלמעלה", מקומפוננטת האב, וזרימת המידע הזאת היא חד-כיוונית - מלמעלה למטה. אם קומפוננטת בת צריכה "לשנות" משהו, היא לא עושה זאת ישירות על ה-props, אלא קוראת לפונקציה שקיבלה כ-prop (כמו onAddToCart בדוגמה למעלה), שנותנת לקומפוננטת האב את ההזדמנות לעדכן את עצמה.

function ProductCard({ name, price }) {
  price = price * 0.9; // אל תעשו את זה - שינוי ישיר של prop
  return <p>{price}</p>;
}

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

למה זה כל כך יסודי להבין

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

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

לסיכום

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

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

הצטרפו לקהילה בדיסקורד