روشها و قلابهای چرخه زندگی React – راهنمای مبتدیان
React تماماً در مورد ساخت رابط کاربری است. و برای انجام این کار به طور موثر، React راه هایی را برای کامپوننت ها فراهم می کند تا چرخه عمر خود را مدیریت کنند.
این بدان معناست که کامپوننت ها می توانند وظایف خاصی را در مراحل مختلف وجود خود انجام دهند، از لحظه ای که ایجاد می شوند تا زمانی که از رابط کاربری حذف می شوند.
روشهای چرخه حیات برای سالها بخش اساسی React بودهاند. اما با معرفی هوکها، رویکرد React برای مدیریت حالت و عوارض جانبی در اجزای عملکردی بصریتر و انعطافپذیرتر شده است.
فقط یک نکته سریع: اگرچه قلاب ها به طور کلی جایگزین اجزای کلاس می شوند، اما هیچ برنامه ای برای حذف کلاس ها از React وجود ندارد.
چرا این راهنما؟
در این آموزش، شما با متدهای چرخه حیات جزء کلاس مانند componentDidMount
، componentDidUpdate
، componentWillUnmount
و shouldComponentUpdate
آشنا خواهید شد.
همچنین قلابهای React مانند useState
، useEffect
و useContext
را کاوش خواهید کرد و دلیل معرفی آنها را درک خواهید کرد. این کار سفر React شما را روانتر و لذت بخش تر می کند.
چه تازه کار با React را شروع کرده باشید یا به دنبال تعمیق درک خود باشید، این راهنما شما را با دانشی که برای ساختن برنامه های وب واکنشگرا و تعاملی با استفاده از ابزارهای قدرتمند React نیاز دارید، مجهز می کند.
بیایید غواصی کنیم و جادوی روش ها و قلاب های چرخه حیات React را کشف کنیم.
چرخه حیات کامپوننت چگونه کار می کند
در React، کامپوننت ها یک چرخه حیات متشکل از مراحل مجزا را طی می کنند. هر یک از این مراحل روشهای خاصی را ارائه میدهد که میتوانید آنها را برای اجرای کد در لحظات مختلف در طول وجود یک جزء سفارشی کنید.
این روشها به شما کمک میکنند تا کارهایی مانند مقداردهی اولیه دادهها، مدیریت بهروزرسانیها و مرتب کردن منابع را در صورت نیاز انجام دهید.
روشهای چرخه حیات اجزای کلاس
بیایید با نگاهی به متدهای چرخه حیات جزء کلاس شروع کنیم. اینها راه اصلی مدیریت چرخه عمر اجزا قبل از معرفی هوک ها بودند.
نحوه استفاده از componentDidMount
:
این پس از درج یک جزء در DOM فراخوانی می شود. این یک مکان عالی برای انجام وظایف راهاندازی اولیه، مانند واکشی دادهها از یک API یا راهاندازی شنوندگان رویداد است.
مثال کد:
import React, { Component } from 'react'; class MyComponent extends React.Component { constructor() { super(); this.state = { data: null, }; } componentDidMount() { // This is where you can perform initial setup. // In this example, we simulate fetching data from an API after the component has mounted. // We use a setTimeout to mimic an asynchronous operation. setTimeout(() => { const fetchedData = 'This data was fetched after mounting.'; this.setState({ data: fetchedData }); }, 2000); // Simulate a 2-second delay } render() { return ( <div> <h1>componentDidMount Example</h1> {this.state.data ? ( <p>Data: {this.state.data}</p> ) : ( <p>Loading data...</p> )} </div> ); } } export default MyComponent;
در این مثال، ما یک جزء کلاس به نام MyComponent
ایجاد کردیم. در سازنده، وضعیت کامپوننت با مجموعه داده ها به null مقداردهی اولیه می شود و ما از آن برای ذخیره داده های واکشی شده استفاده می کنیم.
در روش componentDidMount
، ما واکشی دادهها از یک API را با استفاده از setTimeout
شبیهسازی میکنیم تا یک عملیات ناهمزمان را تقلید کنیم. پس از ۲ ثانیه (۲۰۰۰ میلی ثانیه)، وضعیت مؤلفه با داده های واکشی شده به روز می شود.
در روش رندر، محتوا به صورت مشروط بر اساس وضعیت داده ارائه می شود. اگر داده ها تهی باشند، یک پیام Loading data...
نمایش داده می شود. در غیر این صورت، داده های واکشی شده نمایش داده می شود.
هنگامی که از این کامپوننت در برنامه خود استفاده می کنید، متوجه خواهید شد که ابتدا پیام Loading data... نمایش داده می شود و پس از ۲ ثانیه، داده های واکشی شده نمایش داده می شود. این نشان می دهد که چگونه componentDidMount
برای انجام وظایف پس از اضافه شدن یک جزء به DOM مفید است.
نحوه استفاده از componentDidUpdate
B:
این پس از رندر شدن مجدد کامپوننت به دلیل تغییر در وضعیت یا پروپ های آن نامیده می شود. این یک مکان عالی برای رسیدگی به عوارض جانبی یا انجام اقدامات اضافی بر اساس آن تغییرات است.
مثال کد:
import React, { Component } from 'react'; class Counter extends React.Component { constructor() { super(); this.state = { count: 0, }; } // This method will be called when the "Increment" button is clicked handleIncrement = () => { this.setState({ count: this.state.count + 1 }); }; // componentDidUpdate is called after the component updates componentDidUpdate(prevProps, prevState) { // You can access the previous props and state here console.log('Component updated'); console.log('Previous state:', prevState); console.log('Current state:', this.state); } render() { return ( <div> <h1>Counter</h1> <p>Count: {this.state.count}</p> <button onClick={this.handleIncrement}>Increment</button> </div> ); } } export default Counter;
در این مثال کد، ما یک جزء کلاس Counter
با سازنده ای ایجاد می کنیم که حالت count
را به ۰ مقداردهی اولیه می کند. متد handleIncrement
با کلیک روی دکمه Increment ، وضعیت شمارش را به روز می کند.
در روش چرخه حیات componentDidUpdate
، ما یک پیام (Component updated) را به کنسول وارد می کنیم. ما همچنین هر دو حالت قبلی (prevState) و وضعیت فعلی (this.state) را ثبت می کنیم. این نشان می دهد که چگونه می توانید به مقادیر قبلی و فعلی در طول یک به روز رسانی دسترسی داشته باشید. روش رندر تعداد فعلی و دکمه ای برای افزایش آن را نمایش می دهد.
اکنون، هنگامی که از این جزء Counter
در برنامه خود استفاده می کنید، کنسول مرورگر را باز کنید. هر بار که روی دکمه Increment کلیک می کنید، پیام هایی را در کنسول مشاهده خواهید کرد که نشان می دهد مؤلفه به روز شده است، همراه با مقادیر وضعیت قبلی و فعلی.
میتوانید از componentDidUpdate
برای اهداف مختلفی استفاده کنید، مانند درخواستهای شبکه در هنگام تغییر وضعیت یا پروپوزال، بهروزرسانی DOM بر اساس تغییرات وضعیت، یا تعامل با کتابخانههای شخص ثالث پس از بهروزرسانی. این روشی را برای انجام اقداماتی ارائه می دهد که باید به طور خاص پس از رندر شدن مجدد یک مؤلفه انجام شوند.
نحوه استفاده از componentWillUnmount
این درست قبل از حذف یک جزء از DOM فراخوانی می شود. این مکان بسیار مهمی برای انجام کارهای پاکسازی، مانند پاک کردن تایمرها، لغو اشتراک از رویدادها، یا انتشار منابع برای جلوگیری از نشت حافظه است.
بیایید یک کامپوننت ساده React را نشان دهیم که با استفاده از روش componentDidMount
تایمر را هنگام نصب تنظیم میکند، و زمانی که با استفاده از روش componentWillUnmount
آن تایمر را جدا میکند، آن را پاک میکند.
مثال کد:
import React, { Component } from 'react'; class TimerComponent extends React.Component { constructor() { super(); this.state = { seconds: 0, }; this.timer = null; // Initialize the timer } // When the component mounts, start the timer componentDidMount() { this.timer = setInterval(() => { this.setState({ seconds: this.state.seconds + 1 }); }, 1000); // Update every 1 second (1000 milliseconds) } // When the component unmounts, clear the timer to prevent memory leaks componentWillUnmount() { clearInterval(this.timer); } render() { return ( <div> <h1>Timer Component</h1> <p>Elapsed Time: {this.state.seconds} seconds</p> </div> ); } } export default TimerComponent;
در این مثال کلاس TimerComponent
را ایجاد کردیم. در داخل سازنده، وضعیت کامپوننت با خاصیت seconds مقداردهی اولیه می شود، که ما از آن برای پیگیری زمان سپری شده استفاده می کنیم. متغیر تایمر نیز روی null تنظیم شده است.
در روش چرخه حیات componentDidMount
، تایمر با استفاده از setInterval
شروع می شود. این تایمر هر ثانیه خاصیت حالت ثانیه را افزایش می دهد.
در روش چرخه حیات componentWillUnmount
، تایمر با استفاده از clearInterval
پاک میشود تا اطمینان حاصل شود که پس از حذف مؤلفه از DOM به کار خود ادامه نمیدهد.
در روش رندر زمان سپری شده بر اساس خاصیت وضعیت seconds نمایش داده می شود.
هنگامی که از این TimerComponent
در برنامه خود استفاده می کنید و آن را رندر می کنید، متوجه خواهید شد که تایمر زمانی که کامپوننت نصب می شود شروع می شود و زمانی که کامپوننت خارج می شود متوقف می شود. این به لطف پاکسازی انجام شده در روش componentWillUnmount
است. این از نشت منابع جلوگیری می کند و آن را تضمین می کند
تایمر در طول چرخه عمر قطعه به درستی مدیریت می شود.
نحوه استفاده shouldComponentUpdate
ما از این روش چرخه عمر استفاده می کنیم تا کنترل کنیم که آیا یک مؤلفه باید زمانی که حالت یا پروپ های آن تغییر می کند دوباره رندر شود یا خیر. به ویژه برای بهینه سازی عملکرد با جلوگیری از رندرهای غیر ضروری مفید است.
بیایید یک کامپوننت کلاس React ساده بسازیم و از متد shouldComponentUpdate
استفاده کنیم تا تصمیم بگیریم که آیا کامپوننت باید بر اساس تغییرات در وضعیتش دوباره رندر شود یا خیر.
مثال کد:
import React, { Component } from 'react'; class Counter extends React.Component { constructor() { super(); this.state = { count: 0, }; } shouldComponentUpdate(nextProps, nextState) { // Allow the component to re-render only if the count is even if (nextState.count % 2 === 0) { return true; // Re-render } return false; // Don't re-render } incrementCount = () => { this.setState((prevState) => ({ count: prevState.count + 1 })); }; render() { return ( <div> <h1>Counter Example</h1> <p>Count: {this.state.count}</p> <button onClick={this.incrementCount}>Increment</button> </div> ); } } export default Counter;
در این مثال، ما جزء کلاس Counter
را ایجاد کردیم که یک حالت شمارش را حفظ می کند، که از ۰ شروع می شود. در متد shouldComponentUpdate
، تحلیل می کنیم که آیا تعداد حالت بعدی زوج است یا خیر. اگر اینطور است، اجازه می دهیم کامپوننت دوباره رندر شود. در غیر این صورت از رندر مجدد جلوگیری می کنیم.
متد incrementCount
زمانی فراخوانی می شود که دکمه Increment کلیک شود. این حالت شمارش را با افزایش آن به روز می کند.
در روش رندر، شمارش جاری و دکمه ای برای افزایش آن نمایش داده می شود.
اگر روی دکمه Increment کلیک کنید و شمارش به یک عدد فرد تبدیل شود، مؤلفه دوباره رندر نمیشود. این رفتار نشان میدهد که چگونه میتوان shouldComponentUpdate
برای بهینهسازی رندر در شرایطی استفاده کرد که در آن همه تغییرات حالت نباید باعث رندر مجدد شوند.
معرفی React Hooks
React هوک های معرفی شده در نسخه ۱۶.۸. آنها به اجزای تابعی دسترسی به حالت و ویژگی های مختلف React را بدون نوشتن مولفه های کلاس اعطا کردند.
در نتیجه، اجزای کلاس تا حد زیادی غیر ضروری شده اند. قلابها منطق مؤلفه را سادهتر میکنند و آن را قابل استفادهتر میکنند.
چرا از Hooks استفاده کنیم؟
هوک ها برای رفع چندین مشکل و درک و نگهداری کد React معرفی شدند:
پیچیدگی - هنگام مدیریت وضعیت و عوارض جانبی، اجزای کلاس می توانند پیچیده شوند.
قابلیت استفاده مجدد – منطق در اجزای کلاس به راحتی بین اجزا قابل اشتراک گذاری نیست.
منحنی یادگیری - اجزای کلاس منحنی یادگیری تندتری را برای تازه واردان به React معرفی می کنند.
React Hooks معمولا مورد استفاده قرار می گیرد
قلاب useState
useState
به شما امکان می دهد حالت را به اجزای عملکردی اضافه کنید. آرایه ای را با مقدار وضعیت فعلی و تابعی برای به روز رسانی آن برمی گرداند.
مثال کد:
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); }
در این مثال، ما از قلاب useState
برای مدیریت وضعیت یک شمارنده استفاده کردیم. وقتی دکمه Increment کلیک میشود، setCount
وضعیت شمارش را بهروزرسانی میکند و باعث میشود که مؤلفه با مقدار بهروزرسانیشده دوباره رندر شود.
قلاب useEffect
useEffect
برای عوارض جانبی در کامپوننت های کاربردی، مشابه componentDidMount
و componentDidUpdate
استفاده می شود. پس از رندر اجرا می شود و با تعیین وابستگی ها قابل کنترل است.
مثال کد:
import React, { useState, useEffect } from 'react'; function Example() { const [data, setData] = useState(null); useEffect(() => { // Fetch data from an API fetch('https://api.example.com/data') .then(response => response.json()) .then(data => setData(data)); }, []); // Empty dependency array, runs only once return <div>{data ? data.message : 'Loading...'}</div>; }
در این مثال، useEffect
برای واکشی دادهها از یک API هنگام نصب مؤلفه استفاده میشود. آرایه وابستگی خالی []
تضمین می کند که افکت فقط یک بار اجرا می شود.
هنگامی که دادهها واکشی میشوند، setData
وضعیت دادهها را بهروزرسانی میکند و باعث میشود که اطلاعات واکشی شده دوباره ارائه شود.
قلاب useContext
useContext
به اجزای تابعی اجازه می دهد تا به مقادیر زمینه دسترسی داشته باشند. این روشی است برای انتقال داده به درخت کامپوننت بدون ارسال صریح props.
مثال کد:
import React, { useContext } from 'react'; // Create a context const MyContext = React.createContext(); function MyComponent() { const value = useContext(MyContext); return <div>Context Value: {value}</div>; }
در این مثال، زمینه ای به نام MyContext
ایجاد می کنیم. قلاب useContext
به MyComponent
اجازه می دهد تا به مقدار ذخیره شده در این زمینه دسترسی داشته باشد. این یک ابزار قدرتمند برای مدیریت وضعیت جهانی در برنامه شما است.
مزایای قلاب های سفارشی
قلاب های سفارشی توابعی هستند که از قلاب ها به صورت داخلی استفاده می کنند و می توانند در چندین مؤلفه مجدداً استفاده شوند. آنها به محصور کردن و به اشتراک گذاشتن منطق پیچیده کمک می کنند.
در اینجا نمونه ای از یک هوک سفارشی به نام useLocalStorage
آورده شده است که ذخیره و بازیابی داده ها را در حافظه محلی مرورگر ساده می کند:
import { useState } from 'react'; function useLocalStorage(key, initialValue) { // Retrieve the stored value from local storage const storedValue = localStorage.getItem(key); // Initialize the state with the stored value or the initial value const [value, setValue] = useState(storedValue || initialValue); // Update the local storage whenever the state changes const setStoredValue = (newValue) => { setValue(newValue); localStorage.setItem(key, newValue); }; return [value, setStoredValue]; } export default useLocalStorage;
در این هوک سفارشی، useState
از React وارد می کنیم زیرا از آن برای مدیریت حالت استفاده می کنیم. تابع useLocalStorage
دو پارامتر دارد:
کلید : رشته ای که نشان دهنده کلیدی است که داده ها تحت آن در حافظه محلی ذخیره می شوند.
initialValue
: مقدار اولیه برای حالت.
در داخل هوک، ابتدا سعی کردیم با استفاده از localStorage.getItem(key)
مقدار ذخیره شده را از حافظه محلی بازیابی کنیم. سپس مقدار متغیر state را با استفاده از useState
مقداردهی اولیه کردیم، در صورت وجود از storedValue
یا در غیر اینصورت از initialValue
استفاده می کنیم.
در مرحله بعد، ما یک تابع setStoredValue
را تعریف کردیم که هنگام فراخوانی، حالت و حافظه محلی را به روز می کند. این مقدار جدید را در حافظه محلی با استفاده از localStorage.setItem(key, newValue)
تنظیم می کند.
در نهایت، یک آرایه [value, setStoredValue]
را به عنوان مقدار بازگشتی قلاب برگرداندیم، که به اجزا اجازه می دهد به مقدار ذخیره شده دسترسی داشته باشند و در صورت نیاز آن را به روز کنند.
در اینجا مثالی از نحوه استفاده از قلاب useLocalStorage
در یک کامپوننت آورده شده است:
import React from 'react'; import useLocalStorage from './useLocalStorage'; // Import the custom hook function App() { // Use the custom hook to manage a "username" stored in local storage const [username, setUsername] = useLocalStorage('username', 'Guest'); const handleInputChange = (e) => { setUsername(e.target.value); }; return ( <div> <h1>Hello, {username}!</h1> <input type="text" placeholder="Enter your username" value={username} onChange={handleInputChange} /> </div> ); } export default App;
در این مثال، ما قلاب سفارشی useLocalStorage
را وارد کرده و از آن برای مدیریت مقدار نام کاربری در حافظه محلی استفاده می کنیم. کامپوننت وضعیت نام کاربری را با استفاده از هوک مقداردهی اولیه می کند و زمانی که فیلد ورودی تغییر می کند آن را به روز می کند.
مقدار ذخیره شده و از فضای ذخیره سازی محلی بازیابی می شود و به آن اجازه می دهد در بارگذاری مجدد صفحه باقی بماند.
قلابهای سفارشی روشی قدرتمند برای کپسولهسازی و استفاده مجدد از منطق پیچیده در برنامههای React هستند که کد شما را ماژولارتر و قابل نگهداریتر میکنند.
نتیجه
React ابزارهای قدرتمندی را برای مدیریت چرخه عمر اجزای خود در اختیار توسعه دهندگان قرار می دهد. این چرخههای حیات به اجزا اجازه میدهند تا وظایف خاصی را در مراحل مختلف وجودشان، از ایجاد تا حذف، انجام دهند.
در این راهنما، روشهای چرخه عمر اجزای کلاس React را تحلیل کردهایم. این روشها برای سالها بخش اساسی React بودهاند و همچنان در سناریوهای خاص مرتبط هستند.
شما همچنین با React Hooks آشنا شدید. اینها به روش ترجیحی برای مدیریت حالت و عوارض جانبی در برنامه های React تبدیل شده اند. آنها رویکرد شهودی و انعطاف پذیرتری را برای ساخت اجزا ارائه می دهند.
در حالی که هوک ها محبوبیت پیدا کرده اند و به طور کلی جایگزین نیاز به کامپوننت های کلاس می شوند، مهم است که توجه داشته باشید که هیچ برنامه ای برای حذف اجزای کلاس از React وجود ندارد. پایگاههای کد موجود و کتابخانههای شخص ثالث ممکن است هنوز از اجزای کلاس استفاده کنند، پس درک هر دو چرخه حیات مؤلفه کلاس و قلابها امکانپذیر است.
برای توسعه دهندگان React ارزشمند است.
به طور خلاصه، روشها و قلابهای چرخه حیات React برای ساخت برنامههای کاربردی پویا و کارآمد بسیار مهم هستند و طیف وسیعی از گزینهها را برای مدیریت رفتار و وضعیت اجزا به توسعهدهندگان ارائه میدهند. همانطور که به کاوش و کار با React ادامه می دهید،
متوجه خواهید شد که داشتن درک کامل از چرخه حیات و قلاب ها، شما را به یک توسعه دهنده React همه کاره تر و توانمندتر تبدیل می کند.
اگر این راهنما برای شما مفید و لذت بخش بود، لطفاً آن را لایک کنید. برای آموزشهای روشنتر، برای بهروزرسانیها، من را در X دنبال کنید.
از کدنویسی خود لذت ببرید!
ارسال نظر