چرخه حیات کامپوننت در ری اکت ! Lifecycle در ری اکت
چرخه حیات کامپوننت در ری اکت یکی از مهمترین مباحثی هست که هر توسعه دهنده ی React باید بهش تسلط کامل داشته باشه. Lifecycle در ری اکت یعنی چرخه حیات کامپوننت در ریکت، که از زمان ایجاد شدن اون کامپوننت تا زمان از بین رفتنش رو شامل میشه!
چرخه حیات کامپوننت در ریکت چیست ؟
تو ری اکت، کامپوننت ها یک طول عمر ( چرخه حیات ) دارن !
این چرخه حیات از زمان ساخته شدن اون کامپوننت شروع میشه و تا هنگامی که اون کامپوننت از بین میره، ادامه داره.
تو این حین ما میتونیم رفتار کامپوننت خودمون رو مدیریت کنیم.
مراحل چرخه حیات کامپوننت در ریکت
چرخه حیات کامپوننت در ری اکت شامل سه مرحله میشه :
ایجاد شدن کامپوننت ( mounting ) :
این مرحله زمانی هست که کامپوننت ما ایجاد میشه و وارد DOM میشه. به عبارتی زمانیکه کامپوننت ما متولد میشه و زندگی خودش رو آغاز میکنه، مرحله mounting در کامپوننت میگیم.
تو این مرحله خیلی چیزهارو میشه کنترل کرد که در ادامه بهش اشاره میکنیم.
بروز شدن کامپوننت ( updating ) :
مرحله دوم چرخه حیات کامپوننت در ری اکت ، مرحله updating هست.
به زمانیکه کامپوننت ما به دلیل تغییر State یا تغییر Props، مجدد رندر میشه ( re-render میشه ) مرحله updating میگیم!
این مرحله ممکنه بارها اتفاق بیوفته ( به هر تعدادی که State و Props کامپوننت ما تغییر کنه)
از بین رفتن کامپوننت ( unmounting ) :
مرحله unmounting آخرین مرحله از چرخه حیات کامپوننت در ری اکت هست.
به زمانیکه کامپوننت ما از DOM حذف میشه و دیگه نمایش داده نمیشه، مرحله unmounting کامپوننت میگیم.
تو این مرحله میتونیم کنترل کنیم زمانیکه کامپوننت ما داشت از DOM حذف میشد، چه اتفاقی بیوفته.
خب حالا وقتشه بریم ببینیم چرخه حیات کامپوننت در react شامل چه مراحل و متد هایی میشه و چجوری میشه کنترلش کرد ..
تو ادامه مقاله میخوایم تخصصی تر Lifecycle در ری اکت رو بررسی کنیم. به عنوان یک Front-End Engineer دونستن اینکه Lifecycle در ری اکت شامل 3 فاز اصلی میشه کافی نیست!
ما باید بدونیم که این 3 فاز شامل چه بخش هایی میشن و توسط چه متد هایی در ری اکت میتونیم Lifecycle کامپوننت خودمون رو مدیریت کنیم.
متد هایی که در ادامه درموردش صحبت میکنیم تو Class Component ها کاربرد دارن و در نتیجه در Functional Component ها نمیتونیم ازشون استفاده کنیم. اما زمانیکه هوک ها معرفی شدن، معادل های این متد ها نیز برای Functional Component ها هم معرفی شدن.
1- فاز mounting در چرخه حیات کامپوننت
اشاره کردیم که این فاز ، زمانی هست که کامپوننت ما ساخته میشه و وارد DOM میشه. یا به عبارتی زمانیکه کامپوننت ما متولد میشه رو فاز mounting در lifecycle میگیم.
تو ری اکت، فاز mounting یک کامپوننت رو توسط چندین متد میتونیم کنترل کنیم :
- constructor
- static getDerivedStateFromProps
- render
- componentDidMount
حالا بریم هرکدوم از این متد هارو بررسی کنیم ..
متد constructor :
این متد، اولین متدی هست که در زمان mounting کامپوننت اجرا میشه ( زمانیکه کامپوننت وارد DOM میشه )
از متد constructor معمولا برای مقداردهی اولیه State های کامپوننت خودمون استفاده میکنیم.
این متد اجباری نیست و لزومی نداره که حتما ازش استفاده کنیم. اگه کامپوننت ما Statefull نیست و یا نیاز به مقدار دهی اولیه State های خودمون نداریم، پس اصلا نیاری نیست از متد constructor در ری اکت استفاده کنیم.
نکته ای که وجود داره این هست که متد constructor در زمان قرار گرفتن کامپوننت در DOM اما قبل اولین render اجرا میشه.
همچنین ما باید super(props) رو هم صدا بزنیم، انجام اینکار باعث میشه constructor کامپوننت والد رو صدا بزنیم.
بطور مثال تو تیکه کد زیر ما یک شمارنده ( Counter ) ساختیم که یک constructor داره. تو متد constructor اومدیم state خودمون رو مقدار دهی اولیه ( initialize ) کردیم :
import React from 'react';
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
this.setCount = this.setCount.bind(this);
}
setCount() {
this.setState({count: this.state.count + 1});
}
render() {
return (
شمارنده
عدد فعلی: {this.state.count}
)
}
}
همونطور که مشخصه به کمک متد constructor در مثال بالا تونستیم State خودمون رو مقدار دهیه اولیه کنیم.چرا از constructor استفاده کردیم ؟ چون مقدار دهی اولیه باید در زمان mounting کامپوننت ( متولد شدن کامپوننت ) صورت بگیره.
متد static getDerivedStateFromProps در ری اکت :
مفهوم Props و State کاملا از همدیگه متفاوت هستن، با اینکه خیلی شبیه همدیگه هستن.
به کمک متد getDerivedStateFromProps در ری اکت میتونیم State خودمون رو باتوجه به Props تغییر بدیم. این موضوع زمانهایی خیلی کاربرد داره که State ما قراره از طریق Props دریافت بشه.
متد getDerivedStateFromProps از ما دو آرگومان ورودی دریافت میکنه:
- اولین آرگومان Props
- دومین آرگومان State
خروجی متد getDerivedStateFromProps یک Object یا null هست.
تو فاز mounting ( قرار گرفتن کامپوننت در DOM ) متد getDerivedStateFromProps دقیقا بعد از متد constructor اجرا میشه.
یعنی قبل از اینکه کامپوننت render ( رندر ) بشه.
دونستن اینکه متد getDerivedStateFromProps در ری اکت دقیقا چه کاربردی داره خیلی مهمه. تو مثال زیر کاربرد اصلی این متد ذکر شده :
class UserPreview extends React.Component {
constructor(props) {
super(props);
this.state = {
fullName: ""
};
}
static getDerivedStateFromProps(props, state) {
return {
...
fullName: `${props.firstname} ${props.lastname}`
}
}
render() {
// ...
}
}
به خط 11 تا 16 دقت کنید. متد getDerivedStateFromProps از ما State و Props رو به عنوان آرگومان ورودی گرفته. هر زمان که Props تغییر کنه، State ما با توجه به Props جدید بروزرسانی میشه.
متد render :
این متد تنها متد ضروری برای Class Component ها هست و در فاز Mounting ( قرار گرفتن کامپوننت در DOM ) اجرا میشه.
متد render در ریکت دقیقا بعد از متد قبلی ( getDerivedStateFromProps ) اجرا میشه.
این متد مشخص میکنه که چه چیزی باید به DOM ارائه بشه.
در واقع خروجی متد render یک کد JSX هست که در نهایت اون JSX رندر و نمایش داده میشه. ( اگه با JSX آشنا نیستین، پیشنهاد میکنم مقاله JSX در ری اکت رو مطالعه کنید )
تو مثال زیر میشه روش استفاده از متد render در ری اکت رو دید :
class SubmitButton extends React.Component {
render() {
return (
);
}
}
متد componentDidMount :
آخرین متدی که تو فاز Mounting ( قرار گرفتن کامپوننت در DOM ) اجرا میشه، متد componentDidMount در ری اکت هست.
این متد دقیقا بعد از اولین رندر کامپوننت یا درواقع زمانیکه کامپوننت در DOM قرار گرفته، اجرا میشه.
به کمک متود componentDidMount میتونیم ساید افکت ( side effect ) های خودمون رو اجرا کنیم.( مثل ارسال درخواست های HTTP به سرور و دریافت اطلاعات ) یا بروزرسانی State های کامپوننت.
تو مثال زیر نحوه استفاده از متود componentDidMount در ریکت مطرح شده:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 10
};
}
componentDidMount() {
const myTimer = setInterval(() => {
this.state.count > 0
? this.setState({ count: this.state.count - 1 })
: clearInterval(myTimer);
}, 1000);
}
render() {
return (
عدد:
{this.state.count || "🪐"}
{"⭐".repeat(this.state.count) || "🚀"}
{this.state.count === 0 && LIFT OFF!!!
}
);
}
}
یکی از مرسوم ترین استفاده هایی که میشه از متد componentDidMount کرد، دریافت اطلاعات از سرور یا شروع نمایش یکسری اطلاعات مثل نمایش انیمیشن هست.
2- فاز updating در چرخه حیات کامپوننت
دومین فاز از چرخه حیات کامپوننت در ریکت، فاز Updating هست.
این مرحله دقیقا زمانی هست که State یا Props کامپوننت تغییر میکنه و کامپوننت re-render میشه. تو این فاز متود های زیر اجرا میشن:
- static getDerivedFromProps
- shoildComponentUpdate
- render
- getSnapshotBeforeUpdate
- componentDidUpdate
اگه یادتون باشه، متود getDerivedFromProps و render ، تو فاز قبلی هم اجرا میشدن و اینجا هم اجرا میشن. پس ما سایر متود هارو توضیح میدیم چون این 2 متود رو قبلا معرفی کردیم.
متود static getDerivedStateFromProps :
تو فاز Updating ( هنگام re-render شدن کامپوننت) اولین متودی که اجرا میشه متود getDerivedStateFromProps هست.
این متود زمانی خیلی کاربردیه که Props ما تغییر میکنه و ما میخوایم با توجه به Props تغییر کرده، State خودمون رو بروزرسانی کنیم.
از این متود خیلی کم استفاده میکنیم و در اکثر موارد نباید ازش استفاده کنیم.
متود shouldComponentUpdate :
متود shouldComponentUpdate یکی از متود های جالب اما کم کاربرد ری اکت هست.
از این متود زمانی کمک میگیریم که میخوایم اپیکیشن خودمون رو بهینه تر کنیم ( Performance اپیکیشن رو افزایش بدیم ).
به کمک متود shouldComponentUpdate میتونیم به ری اکت بگیم که درصورت تغییر State یا Props نیازی نیست re-render بشه. ( این اتفاق در حالت عادی میوفته )
این متود کمک میکنه که از re-render های غیرضروری جلوگیری کنیم، اما خیلی با احتیاط باید ازش استفاده کنیم چون ممکنه جاهایی که نیاز به re-render داریم، کامپوننت ما re-render نشه.
این متود 2 آرگومان اختیاری از ما میگیره که عبارتند از : nextProps و nextState
خروجی این متود یک مقدار boolean هست که تعیین میکنه کامپوننت ما re-render بشه یا نشه .مقدار پیشفرض true هست که باعث میشه درصورت تغییر State یا Props، همیشه re-render داشته باشیم.
تو مثال زیر، نحوه استفاده از متود shouldComponentUpdate مطرح شده :
class ShowWholeNumber extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return Math.round(nextProps.num) === Math.round(this.props.num);
}
render() {
return (
مقار تصادفی: {Math.round(this.props.num)}
)
}
}
متود getSnapshotBeforeUpdate :
این متود به ما اجازه میده که به مقدار قبلی Props و State دسترسی داشته باشیم. ( قبل بروزرسانی کامپوننت )
این به ما اجازه میده که بررسی های دلخواه خودمون رو روی این Props و State ها انجام بدیم.
یکی از پرکاربرد ترین موارد استفاده از این متود، زمانی هست که ما یک اپیکیشن چت آنلاین نوشتیم.
فرض کنید کاربر درحال مشاهده پیغام های قدیمی هست و یک پیام جدید دریافت میکنه. چون کاربر در حال مشاهده پیغام های قبلی هست، نباید پیغام های قبلی از دیدش خارج بشه!
در حقیقت به کمک متود getSnapshotBeforeUpdate در ری اکت میتونیم موقعیت اسکرول رو کنترل کنیم.
متود getSnapshotBeforeUpdate در ریکت دقیقا بعد متود render و قبل از متود componentDidUpdate اجرا میشه.
اگه متود getSnapshotBeforeUpdate یک خروجی داشته باشه، این خروجی به عنوان یک آرگومان ورودی به متود componentDidUpdate فرستاده میشه:
class ChatApp extends React.Component {
constructor(props) {
super(props);
this.chatsList = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
if (prevProps.list.length < this.props.list.length) {
const list = this.chatsList.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (snapshot !== null) {
const list = this.chatsList.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
{/* ...contents... */}
);
}
}
متود componentDidUpdate :
این متود آخرین متود اجرا شده در فاز Updating هست.
به کمک متود componentDidUpdate در ری اکت میتونیم ساید افکت ( Side Effect ) های خودمون رو اجرا کنیم. مثل دریافت اطلاعات از سرور ( Http Request ) یا بروزرسانی State های کامپوننت!
متود componentDidUpdate در ریکت میتونه 3 آرگومان از ما بگیره که عبارتند از : prevProps ، PrevState و snapshot .( آرگومان snapshot فقط درصورتی دریافت میشه که از متود getSnapshotBeforeUpdate استفاده کرده باشیم.
تو مثال زیر ویژگی auto save ( ذخیره کردن خودکار ) رو پیاده سازی کردیم :
class WritePost extends React.Component {
constructor(props) {
super(props);
this.state = {
postContent: ""
};
this.handleInput = this.handleInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInput(e) {
this.setState({postContent: this.state.postContent + e.target.value})
}
handleSubmit() {
// ...
}
autosave() {
// send network request to save post...
}
componentDidUpdate() {
this.autosave()
}
render() {
return(
)
}
}
3- فاز unmounting در چرخه حیات کامپوننت
آخرین مرحله از چرخه حیات کامپوننت در ری اکت، فاز unmounting هست. تو این فاز کامپوننت ما از DOM حذف میشه.
در حقیقت فاز unmounting آخرین مرحله از چرخه حیات کامپوننت در ریکت هست.
تو فاز unmounting ، فقط یک متد اجرا میشه و اون componentWillUnmount هست.
بریم ببینیم این متد چیه و چطور Lifecycle در ری اکت تموم میشه ..
متود componentWillUnmount :
متود componentWillUnmount در ری اکت دقیقا قبل از حدف شدن کامپوننت از DOM اجرا میشه. اگه ما بخوایم توی کامپوننت خودمون یکسری موارد clean up اجرا کنیم، باید از این متود استفاده کنیم.
مثل cancel کردن درخواست های شبکه!
بعد از اجرای این متد، کامپوننت از DOM حذف میشه و Lifecycle کامپوننت در ریکت تموم مبشه!
تو مثال زیر نحوه استفاده از متد componentWillUnmount در React مطرح شده. ما فرض رو بر این گرفتیم که از کتابخانه Redux استفاده میکنیم و میخوایم Store خودمون رو unsubscribe کنیم :
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
...
}
// whatever bindings...
}
componentDidMount() {
const { subscribe } = this.props.store;
this.unsubscribe = subscribe(this.forceUpdate);
}
componentWillUnmount() {
this.unsubscribe();
}
render() {
return (
<>
...
>
)
}
}
فاز unmounting آخرین مرحله از چرخه حیات کامپوننت در react بود 🙂
جمع بندی
تو ری اکت، هر کامپوننت سه مرحله مختلف رو پشت سر میزاره. از زمانی که هر کامپوننت ساخته میشه و نمایش داده میشه تا زمانیکه اون کامپوننت حذف میشه و نمایش داده نمیشه، سه فاز رو پشت سر میزاره :
فاز mounting
کامپوننت وارد DOM میشه
فاز updating
زمانیکه State یا Props کامپوننت تغییر کنه و کامپوننت re-render بشه
فاز unmounting
زمانیکه کامپوننت از DOM حذف بشه
هر کدوم از این فاز ها، متد هایی دارن که میتونن اون فاز رو کنترل کنن.
بطور کل چرخه حیات کامپوننت در React یعنی زمانیکه کامپوننت ما ساخته میشه و وارد DOM میشه، تا زمانیکه از DOM حذف میشه.
به کمک lifecycle در ری اکت میتونیم رفتار کامپوننت حودمون رو مدیریت کنیم.
تو این مقاله چرخه حیات کامپوننت در react رو بررسی کردیم و دیدیم که باهاش میتونیم رفتار کامپوننت خودمون رو در شرایط مختلف اون کامپوننت مدیریت کنیم.
امیدوارم که این مقاله براتون مفید واقع شده باشه 🙂
تو ری اکت، کامپوننت ها یک طول عمر ( چرخه حیات ) دارن !
این چرخه حیات از زمان ساخته شدن اون کامپوننت شروع میشه و تا هنگامی که اون کامپوننت از بین میره، ادامه داره.
تو این حین ما میتونیم رفتار کامپوننت خودمون رو مدیریت کنیم.
lifecycle در React تو سه فاز اصلی مدیریت میشه :
- mounting ( زمانیکه کامپوننت وارد DOM میشه )
- updating ( زمانیکه کامپوننت بخاطر تغییر State یا Props مجددا رندر میشه)
- unmounting ( زمانیکه کامپوننت از DOM حذف میشه)
درباره احمد احمدنژاد
من یه برنامه نویس و توسعه دهنده وب هستم که عاشق دنیای صفر و یکم❤️
نوشتههای بیشتر از احمد احمدنژاد2 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
کاملترین مقاله ای بود که درمورد چرخه حیات کامپوننت در ری اکت خوندم 🙂 مرسی از نویسنده محترم این مقاله
سلام و درود
ممنون از نظر لطفتون و خوشحالم که براتون مفید واقع شده 🙂