הרשמה לניוזלטר

הרשמה לניוזלטר

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

Ⓒ כל הזכויות שמורות ל- Fed Cast – קהילת מפתחי הפרונט בישראל

שלושת ההוקים החשובים בריאקט

שלושת ההוקים החשובים למפתחי ריאקט

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

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

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

אז מה זה Hooks?

בהגדרה היבשה שלהם, הוקים הם פונקציות הניתנות לשימוש בקומפוננטות פונקציונליות בלבד.

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

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

לצורך ההמחשה ניתן לראות את ההבדלים בין שתי הדוגמאות הבאות:

קומפוננטה מסוג קלאס

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: props.name
    };
  }

  render() {
    return <h1>Hello, {this.state.name}</h1>;
  }}

קומפוננטה מסוג פונקציה

export default Hello(props) {
  const [name, setName] = useState(props.name)

  return <h1>Hello, {name}</h1>;
}

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

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

כך למשל, useEffect מתחת ל- return שנמצא בתוך תנאי מסוים עלול לא להתקיים, יש לשים את useEffect ברמה העליונה, אם נרצה להתנות אותו אז נוכל להשתמש במשתנה ה- dependencies עליו ארחיב למטה.

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

useState

רגע, מה זה בעצם State?

בהגדרה הפשוטה ביותר, State הוא אובייקט JavaScript המשמש את React כדי להציג מידע בתוך קומפוננטה שיכול להשתנות בהתבסס על פעולה של משתמש.

כל קומפוננטה מנהלת State בנפרד.

בריאקט, ניתן להשתמש ב- state במטרה לשמור מידע ו- props בשביל להעביר את המידע בין קומפוננטות.

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

מאז גרסת 16.8 לכל קומפוננטת ריאקט, בין אם פונקציונלית או class, יכול להיות State.

קריאה ל useState בתוך קומפוננטת פונקציה, יוצרת פיסת state בודדת הקשורה לאותה קומפוננטה.

useState טוב עבור state מקומי בקומפוננטה.

עבור אפליקציה גדולה יותר, העברת מידע בעזרת props היא דרך מסורבלת, הפתרון היעיל יותר, שימוש בRedux או useContext כניהול state (נדבר על פתרונות לניהול state נוספים במאמרים הבאים).

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

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

const [state, setState] = useState(initialstate)

בעת שינוי ב- state מתבצע רינדור חדש של ה- view.

בשביל להשתמש בהוק של useState יש צורך לייבא אותו מ- react.

import React, {useState} from "react"
function Example() {
  const [count, setCount] = useState(0);
  return (
   	<div>
     	<p>You clicked {count} times</p>
  	<button onClick={() => setCount(count + 1)}> Click me </button>
 </div>
	);
  }

useEffect

Hook שמפעיל תופעות לוואי עצמאיות בעת רינדור/טעינת הקומפוננטה.

תופעות הלוואי (side effects) הן למעשה, פעולות שקורות מתי שיש צורך לבצע פעולה כלשהי בעקבות פעולה של המשתמש או באחד מה- Life Cycle Methods של הקומפוננטה.

useEffect מקבל 2 ארגומנטים – useEffect(callback, [ dependencies ]);.

Callback היא פונקציה המכילה את הלוגיקה של תופעות הלוואי (side effects).

Dependencies הוא מערך אופציונלי של תלויות, כלומר, useEffect יקרא רק כאשר יש שינוי באחד מה- Dependencies במערך.

אם מערך ה- Dependencies ריק, ה- useEffect callback יקרא פעם אחת בלבד, בעת טעינת/הפעלת הקומפוננטה או רענון הדף.

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

למעשה ההמלצה היא להשתמש במשתנה ה- dependencies כדי להפחית את הסיכויים לתופעות לוואי לא רצויות.

בקומפוננטת class, פונקציה מקבילה ל- useEffect היא componentDidMount.

לאחר שהיא מופעלת יש צורך להפעיל עוד פונקציה componentWillUnmount.

מטרתה להפעיל לוגיקה שתקרא לפני שקומפוננטה מוסרת, לרוב כשצריך לנקות פונקציות טיימר, eventListeners, network requests.

כאשר נשתמש ב- useEffect ונרצה לקרוא לקטע קוד שיופעל בעת ה- componentWillUnmount, נחזיר פונקציה וכך React תפעיל אותה לפני שהקומפוננטה מוסרת.

זהו מנגנון הניקוי האופציונלי ל- useEffect.

על ידי ניקוי זה, נוכל למנוע מהאזנה מיותרת של events מספר פעמים ומדליפות זיכרון.

function Example() {
  const [state, setState] = useState('');
  useEffect(() => {
    // will run once at page load.
    // will run again when the specific value in the dependencies array changes.
    return function cleanupListener() {
      window.removeEventListener(eventName, function)
    }
  }, [state]);
}

ל- useEffect יכולים להיות מספר שימושים, לדוגמא:

  • טעינת נתונים משרת מרוחק כאשר קומפוננטה נטענת/מתרנדרת.
  • להריץ קוד כאשר state או prop משתנה.
  • מניפולציות ישירות על ה- DOM.
  • שימוש בפונקציות timers, setInterval, console.log ועוד.

useContext

בהתאם למה שכתבתי בתחילת המאמר, על state והעברת מידע בין קומפוננטות הורה/ילד בעזרת props, זה תרחיש שלא עובד היטב כאשר יש לנו state גלובלי או העברה לקומפוננטות בהיררכיה עמוקה יותר (nested components).

זו בעיה, שניתן לפתור בעזרת useContext, ע״י יצירת contextAPI שמאפשר שיתוף מידע ללא שימוש ב- props וללא תלות בהיררכיה שבין הקומפוננטות.

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

useContext דורש 3 צעדים: יצירת ה- context, העברתו דרך Context.Provider ושימוש במידע בתוך הקומפוננטה הרצויה.

import { createContext, useContext } from "react";

const context = createContext("initial data");

export function App() {

  const data = "useContextData";

  return (
	<Context.Provider value={data}>
  	<MyComponent />
	</Context.Provider>
  );
}
 
function ExampleComponent() {
  const data = useContext(context);
  return <span>{ data }</span>;
}

לסיכום

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

useSate, use Effect ו- useContext הם ההוקים הבסיסיים ביותר שכל מפתח ריאקט חייב להכיר, למעשה הם אבני היסוד ליצירת קומפוננטות מסוג פונקציה.

לשאלות בנושא, מוזמנים לפנות אליי. ניר ארגיל, Frontend Developer.

שלום לך 👋 נעים להכיר.

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

אנחנו לא שולחים ספאם!

רוצים לקבל מאיתנו עדכונים?

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

הרשמה לניוזלטר

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