در جلسه قبل در رابطه با چیزی به نام Lifecycle صحبت کردم اما هنوز آن را به شما معرفی نکرده ام. بنابراین می خواهیم در این جلسه با Lifecycle در ری اکت آشنا شویم.
اولین نکته ای که باید بدانید این است: Lifecycle ها فقط و فقط در کامپوننت های کلاس-محور قابل دسترسی هستند. در نسخه جدید react کامپوننت های کاربردی (functional) نیز نوعی hook دارند که تقریبا معادل Lifecycle است اما خود Lifecycle فقط در کامپوننت های کلاس-محور موجود است.
نکته دوم این است که نام گذاری Lifecycle hooks برنامه نویسان را به اشتباه می اندازد. به چه خاطر؟ به دلیل اینکه درون نامش hooks دارد افراد مبتدی تصور می کنند که جزئی از react hooks است (مثلا دستور useState) اما باید بدانید که Lifecycle hooks هیچ ربطی به react hooks ندارد و تنها یک نام گذاری عجیب از سمت گروه react است.
Lifecycle hooks به متدهای زیر گفته می شود:
React می تواند این متدها را برای ما اجرا کند که هر کدام کارهای مختلفی انجام می دهند. ما برای راحتی کار آن ها را به چند دسته تقسیم کرده ایم. فعلا به صورت تئوری با این موارد آشنا می شویم سپس به صورت عملی تک تک آن ها را به شما نشان خواهم داد بنابراین نگران نباشید.
الف) زمانی که یک کامپوننت ساخته می شود (constructor(props
اجرا می شود. البته constructor جزو lifecycle hook ها نیست بلکه یکی از ویژگی های کلاس ها در جاوا اسکریپت ES6 است.
نکته: اگر بخواهید constructor خود را بنویسید و آن را صدا بزنید برای دسترسی به props باید از تابع (super(props را صدا بزنید. (ر.ک به جلسات مروری بر ES6).
اگر با کلاس ها در هر زبان برنامه نویسی آشنا باشید می دانید که کار constructor آماده سازی و ساختار دهی اولیه است؛ به طور مثال می خواهید زمانی که یک شیء از آن کلاس ساخته شد دارای یک state پیش فرض باشد. اما حواستان باشد که درون constructor ها side-effect ایجاد نکنید؛ side-effect در لغت به معنی «عوارض جانبی» است اما در react زمانی که می گوییم side-effect منظورمان چیز هایی مثل ارسال درخواست HTTP یا ذخیره چیزی در مرورگر کاربر یا ارسال آمار به google analytics و... چرا که این کارها باعث کند شدن برنامه شما و re-render های پیاپی می شوند که سرعت سایت شما را شدیدا پایین می آورند.
وب سایت react خودش این مثال را می زند:
فرض کنید کد زیر را داشته باشیم:
class Clock extends React.Component { render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.props.date.toLocaleTimeString()}.</h2> </div> ); } }
حالا فرض کنید می خواهیم date را از props به state ببریم. در این صورت ابتدا this.props.date را با this.state.date عوض می کنیم:
class Clock extends React.Component { render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2> </div> ); } }
سپس constructor را صدا می زنیم:
class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2> </div> ); } }
سپس props را پاس می دهیم:
constructor(props) { super(props); this.state = {date: new Date()}; }
سپس date را که prop بود از عنصر clock حذف می کنیم:
ReactDOM.render( <Clock />, document.getElementById('root') );
نتیجه نهایی:
class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2> </div> ); } } ReactDOM.render( <Clock />, document.getElementById('root') );
البته در جلسه بعد از constructor در پروژه خودمان استفاده خواهیم کرد.
ب) پس از اجرای constructor یک متد دیگر به نام (getDerivedStateFromProps(props, state
اجرا می شود. این متد یک lifecycle hook است که در react 16.3 معرفی شد. فایده این متد این است: زمانی که props کامپوننت های کلاس-محور شما تغییر می کند، می توانید state خود را با آنها sync (همگام سازی) کنید. چنین موقعیتی به ندرت اتفاق می افتد. بنابراین اکثر برنامه نویسان هیچ وقت از این lifecycle hook استفاده نمی کنند. به طور مثال اگر در موقعیتی باشید که props کامپوننت شما نمی تواند تغییر کند و شما می خواهید state درونی آن کامپوننت را تغییر دهید، می توانید از این متد استفاده کنید! تمام این موارد را بعدا و به صورت عملی به شما نشان خواهم داد. مثل همیشه نباید در این قسمت side-effect ایجاد کنید.
پ) پس از اجرای این دو متد، متد ()render اجرا می شود. حتما با این متد آشنایی دارید؛ این متد همان متدی است که کدهای JSX را برمیگرداند. بله تمام کار این متد آماده سازی و برگرداندن کدهای JSX است و شما نیز باید فقط برای همین کار از آن استفاده کنید.
در نظر داشته باشید که اگر در این متد از کامپوننت های دیگری استفاده کرده باشید، پس از صدا زدن render آن کامپوننت های فرزند نیز باید render شوند بنابراین این متد برای آن ها نیز اجرا می شود.
ت) در آخر نیز متد componentDidMount صدا زده می شود. در این متد است که می توانید side-effect ایجاد کنید. معمولا از این متد استفاده می شود تا درخواست های HTTP ارسال شوند و داده های جدیدی از سمت وب گرفته شوند. شما نباید به هیچ عنوان درون این متد state را تنظیم کنید. بنابراین از setState دوری کنید چرا که باعث re-render های متعدد می شود. زمانی که می گوییم باعث re-render می شود یعنی تمام این چرخه (قسمت creation مربوط به lifecycle) دوباره اجرا می شود که به نوبه خود باعث افت شدید سرعت خواهد شد (مخصوصا اگر چندین بار اتفاق بیفتد).
در جلسه بعد این موارد را به صورت عملی بررسی خواهیم کرد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.