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

ה-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 לקומפוננטת ריאקט.

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

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

פתרונות ומאמרים על פיתוח אינטרנט

נגישות טכנית – פודקאסט ומבוא

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

פתרונות ומאמרים על פיתוח אינטרנט

המנעו מהעלאת source control לשרת פומבי

לא תאמינו כמה אתרים מעלים את ה-source control שלהם לשרת. ככה תמצאו אותם וגם הסבר למה זה רעיון רע.

ספריות ומודולים

מציאת PII באמצעות למידת מכונה

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

מיקרו בקרים

הפעלת מסך oled קטנטן עם esp32

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

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