ריאקט - הבסיס
vite
כלי לבניית תכנית ווב בצורה מהירה:
ניתן להשתמש במנגנון ה-template create
כדי ליצור פרוייקטי ריאקט בלי מאמץ.
מריץ גם את השרת.
מה זה ריאקט?
זהו פריימווק דקלרטיבי לממשק משתמש.
מה זה קומפוננטה
הגדרה עצמאית שניתן להשתמש בה באופן חוזר לרכיב בממשק משתמש.
ליצור קומפוננטה
החזרה עם סוגריים מעוגלות שאומר שזה קוד HTML בתוך קוד JS.
1 | function Header() { |
אפשר להשתמש בזה באופן הבא:
1 | function App() { |
Build in comps
lowercase
html elements
dom nodes
Custom comps:
uppercase
defined by u - wraps built in
react traverse until it recognizes only built in comps
ערכים דינמיים בקומפוננטה
כדי להוסיף ערכים יש להשתמש ב-{}
.
1 | return ( |
ערכים דינמיים לתכונות HTML
ניתן לעשות import
לקבצי css
וקבצים אחרים.
1 | import reactImg from "./assets/react-core-concepts.png"; |
העברת מידע בעזרת props
1 | function CoreConcept(props) { |
או בעזרת desctruction
ניתן להשתמש באובייקטים ואז לפצל אותם לתכונות:
1 | function CoreConcept({ image, title, description }) { |
פיצול קומפוננטה לקובץ
בקובץ אחר נרצה להוסיף export default
במידה וזה הדבר היחידי בקובץ:
1 | export default function CoreConcept({ image, title, description }) { |
ולעדכן imports
.
import XXX.css
כאשר מייבאים קבצי CSS
יש לשים לב שכל האלמנטים ייקבלו את העיצוב גם אם אנחנו נרצה את זה רק לקומפוננטה אחת.
props children
ניתן להעביר ערכים גם בעזרת הילדים:
1 | function MyComp(props){ |
השימוש בילדים זה אופציה מהירה יותר ומאפשר אנקפסולציה לקוד JSX
.
כמו כן גם מאפשר כתיבה שדומה יותר לקוד HTML
.
אם צריך לשלוט בצורה טובה יותר במידע שעובר אז שימוש בתכונות ספציפיות יותר טוב.
Component listeners
ניתן להעביר פונקציות על מנת להפעיל התנהגות:
1 | export default function TabButton({ children, onClick }) { |
ניתן להשתמש בפוקנציות חצים כדי לקנפג קריאה אחרת
1 | export default function TabButton({ children }) { |
מומלץ להחזיר callable
לאירוע.
לעדכן את ריאקט שה-UI שלנו השתנה
אם סתם נזרוק משתנה לתוך הקוד, ריאקט לא יידע שהוא ישתנה:
1 | let myName = "Shrek": |
הקומפוננטה תרוץ רק פעם אחת!
כדי לתקן את זה צריך להשתמש במשהו שנקרא React hook
.
מה שנשתמש בו הוא useState
1 | import { useState } from "react"; |
חייבים לקרוא לפונקציה ברמה בגבוה
- חייבים להשתמש בזה בתוך קומפוננטה ולא מחוץ.
- חייבים לקרוא לזה בהתחלה ולא בתוך תנאי או משהו פנימי
למשל זה אסור:
1 | function App(){ |
עדכון של הUI
1 | let myName = "Shrek": |
אם לרנדר או לא לרנדר - תנאים
אפשר לקצר עם ?:
או עם &&
.
דרך ראשונה - ?:
1 | {!selectedTopic ? <p>Please select an example.</p> : null} |
דרך שנייה - &&
1 | {selectedTopic && ( |
דרך שלישית - if else
1 | let tableContent = <p>Please select a topic</p>; |
Styling using classes
בתוך JSX
אנחנו משתמשים ב-className
.
1 | <button className={isSelected ? 'active' : undefined}>Click me </button> |
ניתן להשתמש בכמה קלאסים
1 | <button className="btn btn-primary">Click</button> |
Listing
בקצרה השתמשו ב-map
כדי ליצור ממערך רשימה של קומפוננטות.
1 | {CORE_CONCEPTS.map((core) => ( |
השתמשו ב-key
כדי לומר ל-react
איך ל
React - Deep dive
ריאקט עובד בתצורת קומפילציה - הוא בונה ומאפטמז את הקוד ומייצר קבצים שניתן להריץ בדפדפן.
להשתמש בפונקציות createElement
האם חייבים JSX
?
ניתן גם לייצר אלמנטים בעזרת פונקציות בנויות של ריאקט.
1 | React.createElement( |
==
1 | <div id="content"> |
בתצורה של הפונקציות לא צריך באמת לבנות קבצי JSX
.
JSX
הוא בסופו של דבר תוסף שיש לו תהליך בנייה משלו.
בעזרת קריאה ישירה לפנוקציית ג’אווהסקריפטית אז נמנע מתהליך הבנייה.
Fragments
אלמנטים JSX
צריכים שיהיה להם אלמנט שורש:
אסור:
1 | <Header></Header> |
חייבים:
1 | <div> |
הסיבה העיקרת לכך שאי אפשר להחזיר 2 ערכים אלה רק ערך אחד לאלמנט.
שחייבים להחזיר אלמנט אחד לכל אלמנט ב-JSX
.
במקום שיהיה לנו div
נוסף נוכל להשתמש באלמנט Fragment
.
1 | import Fragment from 'react'; |
תחביר חדש מאפשר לכתוב פרגמנטים בצורה ריקה
1 | <> |
פיצול קומפוננטות
קומפוננטות עוקבות אחרי SRP,
כדי שכל קומפוננטה תתעסק במשהו אחד.
הסיבה השנייה היא כדי שקומפוננטות שמשתנות לא ייצטרכו להריץ את כל הקוד מחדש.
תתארו לכם שאם האפליקציה שלכם היא קומפוננטה אחת, כל האפליקציה תתעדכן בעדכון משהו בודד.
פיצול קומפוננטות ע”פ פיצ’רים או סטייט
יתרונות בפיצול קומפוננטות:
- ארגון יותר טוב של הקומפוננטות והלוגיקה.
- ניתן לנהל את הסטייט בצורה יותר חלקה
- ניתן לייבא ולייצא אלמנטים בצורה קלה ומודולרית
- אפליקציה נקייה
תכונות של אלמנטים לא עוברים ישירות לקומפוננטה
המאפיין id
לא עובר לתוך האלמנט, הרנדרר מתעלם מהמפאיינים האלו.
1 | <Section id="examples"> |
זה לא עובר לתוך האלמנט section
:
1 | function Section({title,chidlren}){ |
כדי להעביר אותם צריך להעביר אותם ידנית:
1 | <Section id="examples"> |
זה לא עובר לתוך האלמנט section
:
1 | function Section({title,id, chidlren}){ |
Forwarding props
בעזרת פיצ’ר של ג’אווה סקריפט שנקרא Rest Properties
נוכל להעביר כל מיני פרמטרים ישירות בקלות.
ואז נצטרך לבצע Deconstruction
על האלמנט:
1 | function Section({title,chidlren, ...props}){ |
Using JSX Slots - Multiple slots
כבר למדנו שאפשר להעביר ילדים לקומפוננטה, זה מאפשר לנו לרנדר אותם בתוך האלמנט.
אולם אם אנחנו צריכים להעביר יותר אלמנטים מאשר ילדים?
לזה קוראים Multiple Slots
:
1 | <Card |
בניית קומפוננטות דינמיות על ידי העברת הטייפ
ניתן להעביר את הטייפ של קומפוננטה או אלמנט על מנת ליצור קומפוננטה חדשה ממנה
בשביל אלמנט שלנו נצטרך שזה יתחיל באות גדולה למשל - MyTitle
.
אם נרצה להעביר אלמנט קיים נצטרך להעביר מחרוזת כמו "h2"
.
1 | function MyTitle({chidlren}){ |
יצירת דיפולטים למאפייני קומפוננטה
לעיתים נרצה שקומפוננטה תהיה עם ערכים בסיסיים בברירת מחדל.
ואחר כך אם המשתמש יירצה, לערוך אותה עבורו.
אין פה שום קסם, זה רק פיצ’ר של ג’אווהסקריפט כדי להתחל את זה בצורה פושטה
1 | export default function RedTitle({ titleType = "h1", children }) { |
קומפוננטות הן עצמאיות
כל קומפוננטה היא עצמאית ומבודדת משאר הקומפוננטות, לכן אנו יכולים ליצור הרבה מופעים של אותה קומפוננטה:
1 | <RedTitle>One</RedTitle> |
שינוי סטייט על פי הסטייט הקודם
כאשר אנו משנים את הסטייט של הקומפוננטה והיא תלויה בסטייט הקודם ולא סטייט לגמרי חדש,
אנו צריכים להעביר פונקציה
כן:
1 | setIsEditing(wasEditing => !wasEditing); |
לא:
1 | setIsEditing(!isEditing); |
זה מבטיח שהסטייט האחרון ייקרא בהצלחה ולא יהיה לנו בעיה מבחינת הסטייט האחרון.
הסיבה לכך היא שהמנגנון של ריאקט לא מעדכן ישר את הגרפיקה אלה מתזמן את זה לעתיד.
העתקת אובייקט עדיפה על שינוי הסטייט
כן:
1 | const updateUser = {...user}; |
לא:
1 | const updateUser = {user}; |
מכיוון שהאובייקט זה רפרנס, אנו בטעות משנים את הסטייט השמור - שיכול לגרום לבאגים.
העלאת סטייט לקומפוננטה העליונה
כאשר רוצים לשתף סטייט בין קומפוננטות או כמה קופוננטות צריכות לנהל סטייט משותף הדרך הפשוטה היא לעלות אותו למעלה.
1 | function FirstComp({setName}){ |
שימוש בסטייט יחיד
העקרון בריאקט הוא לנסות לבודד סטייט ולהשתמש בסטייט אחד כדי לייצג את מצב האפליקציה.
למשל במקום לשמור שני סטייטים ללוח משחק ותור של השחקן נוכל לייצג את זה בסטייט אחד - מהלך:
1 | const [player, setPlayer] = useState(); // Who |
1 | const [turns, setTurns] = useState(); // Who and Where |
זה לא בהכרח שומר על עקרון האחריות היחידה אולם במצב הזה אנו נמנעים מלבדוק כמה סטייטים שיכול להיות מצב בעייתי.