מעגל החיים הריאקטי

ה-Lifecycle של קומפוננטת ריאקט

במאמר הקודם למדנו על אירועים בקומפוננטת ריאקט ואיך לנהל אותם כדי שינהלו לנו את ה-state. כשלמדנו על stateful components למדנו על componentDidMount – שהופעלה כאשר הקומפוננטה היתה מוכנה. מאיפה באה המתודה הזו? מדובר בסדרה של מתודות שנקראות לאורך חיי הקומפוננטה. מהיצירה ועד המוות. אנחנו יכולים להשתמש במתודות האלו לצרכים שלנו. בדרך כלל משתמשים בזה לתקשורת עם קומפוננטות אחרות. למשל אם יש לי קומפוננטת אבא (ויש לי בדרך כלל), יש סיכוי שהיא תרצה לדעת כשקומפוננטת הבן מתעדכנת. אם אני מעוניין לעשות את זה, אני צריך לקרוא לפונקציות מסוימות במעגל החיים הריאקטי.

מעגל החיים. מתוך פליקר. Jeff Krause.
מעגל החיים. מתוך פליקר. Jeff Krause.

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

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

<div id='content'></div>
<script type='text/babel'>
    class Counter extends React.Component {
      render() {
        const textStyle = {
          color: 'black',
          fontSize: 72,
          fontWeight: 'bold'
        };

        return (
          <div style={textStyle}>
            {this.props.display}
          </div>
        );
      }
    }

    class CounterParent extends React.Component {
      constructor(props, context) {
        super(props, context);
        console.log('constructor: Default state time!');

        this.state = {
          count: 0
        };

        this.increaseCounter = this.increaseCounter.bind(this);
      }

      increaseCounter() {
        this.setState({
          count: this.state.count + 1
        });
      }

      componentWillUpdate(newProps, newState) {
        console.log('componentWillUpdate - Component is about to update!');
      }

      componentDidUpdate(prevProps, prevState) {
        console.log('componentDidUpdate - Component just updated!');
      }

      componentWillMount() {
        console.log('componentWillMount - Component is about to mount soon!');
      }

      componentDidMount() {
        console.log('componentDidMount - Component just mounted!');
      }

      componentWillUnmount() {
        console.log('componentWillUnmount - Component is about to be deleted');
      }

      shouldComponentUpdate(newProps, newState) {
        console.log('shouldComponentUpdate - Testing if component should update...');

        if (newState.count < 4) {
          console.log('shouldComponentUpdate - Component should update!');
          return true;
        } else {
          ReactDOM.unmountComponentAtNode(target);
          console.log('shouldComponentUpdate - Component should not update!');
          return false;
        }
      }

      componentWillReceiveProps(newProps) {
        console.log('componentWillReceiveProps - Component will get new props!');
      }

      render() {
        const backgroundStyle = {      
          border: 'black 3px dotted',
          borderRadius: 12,
          padding: 20,
          textAlign: 'center',
          width: 250,
        };

        return (
          <div style={backgroundStyle}>
            <Counter display={this.state.count} />
            <button onClick={this.increaseCounter}>+</button>
          </div>
        );
      }
    };

    console.log('defaultProps - Default prop insertion!');
    CounterParent.defaultProps = {

    };

const target = document.getElementById('content');
ReactDOM.render(
  <CounterParent />,
  target
);
</script>

CounterParent היא הקומפוננטה שעליה נשים את ה-console.log כדי לראות את הקריאות השונות. בואו ותכנסו אל הדמו שהכנתי, ממש פה וצפו בקונסולה. נסו ללחוץ על ה׳פלוס׳ ותראו מה קורה. הקומפוננטה הורגת את עצמה אחרי שהקאונטר מגיע ל-3.

הקונסולה במהלך חיי הקומפוננטה
הקונסולה במהלך חיי הקומפוננטה

הדבר הראשון שנראה הוא constructor: Default state time!. ואם תסתכלו בקוד תראו שהוא מופיע ב-constructor. זה הדבר הראשון שקורה. הקוד נטען ומוכן לריצה. הדבר השני שקורה הוא componentWillMount שדי מסביר את עצמו. הסיום הוא componentDidMount שאותו אנחנו מכירים.

השלבים הבאים מתרחשים כאשר אני מעדכן את ה-state. בשביל זה אנחנו צריכים ללחוץ על הכפתור ואז קורים כמה דברים מעניינים עם shouldComponentUpdate אני יכול להבין שהקומפוננטה עומדת להתעדכן. שימו לב שאני משתמש בקומופוננטה הזו כדי להרוג אותה אם הקאונטר עובר את 4. נסו ללחוץ עליה ותראו את שאר האירועים. בדוקומנטציה הרשמית של ריאקט יש הסבר על כל האירועים. שימו לב שלעתים יש שינויים בין גרסה לגרסה. אנחנו משתמשים בגרסה 16. בגרסה 17 לא יהיו אירועי componentWillMount, componentWillReceiveProps, componentWillUpdate – הם פשוט יעלמו. מגרסה 1.3 נקבל התראות על האירועים האלו.

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

במאמר הבא נלמד על חיבור של DOM לקומפוננטת ריאקט.

⚠️אם אהבת את המדריכים על ריאקט – יש ספר מקיף ושלם על ריאקט שכתבתי בשם ללמוד ריאקט בעברית, במסגרת פרויקט עם חברות מובילות ומפתחים אחרים. בספר יש פירוט מקיף יותר על ריאקט ותרגילים רבים ללימוד עצמי. 

פוסטים נוספים שכדאי לקרוא

רספברי פיי

מה זה AIoT? ואיך אפשר להתחיל?

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

בינה מלאכותית

Safeguards על מודל שפה גדול (LLM)

פוסט בשילוב עם פודקאסט וסרטון על ההגנות שאפשר להציב על LLM בסביבת פרודקשן

תמונה מצוירת של רובוט שמנקה HTML
יסודות בתכנות

סניטציה – למה זה חשוב

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

גלילה לראש העמוד