امروز میخواهم پایههای دنیای React را برجستهسازی کنم. اگر تازه سفر خود به ReactJS را شروع کردهاید، پس به جای درستی آمدهاید. در این مقاله، من سعی کردم پایههای React را به هر نحوی پوشش دهم. امیدوارم که در انتهای آن شما مفاهیم اساسی React را بدانید.
بیایید شروع کنیم.
ReactJS - یک کتابخانه قدرتمند
همانطور که شاید در چند جا خوانده باشید، React یک کتابخانه برای ساخت رابطهای کاربری وب و موبایل است. این کتابخانه توسط Facebook توسعه داده شده است.
ReactJS کامپوننت محور است. هر چیزی یک کامپوننت است، که مسئول یک عملکرد میباشد. شما در آن کامپوننتهای کوچکی را مینویسید و سپس آنها را ترکیب میکنید، تا یک کامپوننت عظیم را تشکیل دهید. این کار، کد را خواناتر و قابل درکتر میکند. ویژگیهایی که React را قوی و زیبا میکنند عبارتند از:
۱. ReactJS از مفهوم DOM مجازی به جای DOM واقعی استفاده میکند.
۲. خوانایی کد به خاطر JSX. استفاده از JSX باعث میشود حس کنید در حال نوشتن یک وباپلیکیشن هستید.
۳. ReactJS همچنین از SSR استفاده میکند. (SSR در SEO کمک میکند)
چیزهایی هستند که شاید درباره آنها خوانده باشید، اما پس از خواندن این مقاله آنها را درک کرده و احساس خواهید کرد. پس بیایید به مفهوم DOM مجازی وارد شویم. (به نظر من این ویژگی اصلی است که React را زیباتر میکند)
DOM مجازی
DOM مجازی یک کپی از DOM واقعی است. برخلاف DOM واقعی، DOM مجازی کمترین مقدار دستکاری DOM را انجام میدهد تا کامپوننتها را بروز نگه دارد. DOM مجازی فقط بخشیهایی که بروز شدهاند را بروزرسانی میکند.
دستکاری DOM بسیار آسان است. در اینجا یک نمایش بصری از نحوه کار DOM مجازی را مشاهده مینمایید.
۱. DOM مجازی یک کپی از DOM واقعی است.
۲. وقتی که دادهها در یک کامپوننت تغییر میکنند، کل رابط کاربری مجددا در DOM مجازی رندر میشود.
۳. سپس مقایسه بین DOM واقعی و DOM مجازی شکل میگیرد.
۴. پس از این که محاسبات به اتمام رسیدهاند، DOM واقعی با چیزهایی که تغییر کردهاند بروزرسانی میشود.
ما در حال صحبت درباره یکی از بزرگترین ویژگیهای React بودهایم، که این ویژگی DOM مجازی است. اما صبر کنید! JSX در ویژگی دوم چه بود؟ شاید برای شما سوال شده باشد که JSX چیست، ارتباط آن با React چیست و چگونه حس نوشتن یک وباپلیکیشن را به ما میدهد...
حال وقت آن رسیده است که به JSX وارد شویم.
قبل از ادامه دادن، بیایید نگاهی به کد زیر داشته باشیم:
class FirstComponent extends React.Component {
render() {
return (
<span className='customSize'>My First Component</span>
);
}
}
class FirstComponent extends React.Component {
render() {
return (
React.createElement(
'span',
{className: 'customSize'},
'My First Component'
)
);
}
}
در مثال اول، به نظر میرسد که تابع رندر در حال برگرداندن یک کد HTML میباشد، اما در واقع این کد JSX است. اولین مثال یک نسخه JSX از مثال دوم است. JSX یک افزونه JavaScript است که به کد JS شما یک ظاهر HTML میدهد.
اگر به مثال دوم نگاه کنید، React.createElement برای ساخت یک کامپوننت React استفاده شده است تا نمایانگر کامپوننت React باشد. اگر هیچ prop یا صفتی برای عنصر مورد نظر نیاز نباشد، آرگومان دوم میتواند null یا خالی باشد. آرگومان سوم تعریف میکند که چه چیزی باید داخل آن باشد. (به مانند هر عنصر React دیگری، بر فرض <image> با صفت ‘src’)
اگر به دو بلوک کد بالا نگاهی داشته باشید، پی خواهید برد که بلوک اول آشناتر است؛ زیرا یک احساس HTML به شما میدهد. JSX همچنین خوانایی کد را افزایش میدهد. بیایید نگاهی به یک مثال دیگر بدون JSX و با JSX داشته باشیم، تا خوانایی کد را حس کنیم.
React.createElement("div", null,
React.createElement("img", {src: "image.jpg", alt: "Random photo"}),
React.createElement("h3", null, "Hello React")
);
نسخه JSX:
<div>
<img src="image.jpg" alt="Random photo" />
<h3>Hello React</h3>
</div>
با نگاه به مثال بالا، شما میتوانید چیزی که من درباره خوانایی کد میگفتم را درک کنید. خواندن کد به همراه JSX بسیار آسان است، نه؟ به نظر من همین برای JSX کافی است و امیدوارم که حال بهتر بتوانید قدرت JSX را در دنیای React درک کنید.
نکته: مرورگرها نمیتوانند JSX را بخوانند. پس ما باید آن را با استفاده از تغییر شکل دهندههای JSX (مانند Babel)، به جاواسکریپت transpile کنیم، تا مرورگر بتواند آن را درک کند.
حال ما میدانیم که JSX چیست. اما من دوست دارم به تصویر قبلی بروم که در آن گفتم React به کلی درباره کامپوننتها است. React کامپوننت محور است. با توجه به این که کامپوننتها، بلوکهای ساخت React هستند، بیایید آنها را کاوش کنیم.
کامپوننتها
خب، شاید در طی تحقیقات خود درباره React برای نحوه ساخت کامپوننتها، به این کد برخورده باشید:
class MyStatefulComponent extends React.Component {
state = {
title: ''
}
componentDidMount() {
console.log('Component mounted')
}
render() {
return <div>{this.props.name}</div>;
}
}
اگر شما کامپوننت خود را به مانند بالا میسازید، این کامپوننت یک کامپوننت کلاس (class) / دارای state (stateful) / محفظه (container) نام دارد. اگر فکر میکنید که این تنها راه ساخت کامپوننتها است، دوباره فکر کنید. بله، یک راه دیگر برای ساخت کامپوننتها وجود دارد که به کامپوننتهای تابعی (functional) / بدون state (stateless) / نمایشی (presentational) ختم میشود. قبل از این که ادامه دهیم، بیایید ببینیم که کامپوننتهای تابعی چگونه نوشته میشوند:
const MyStatelessComponent = props => <div>{props.name}</div>;
حال شاید برایتان سوال باشد که تفاوت بین این دو چیست و چگونه باید انتخاب کنید که کدام نوع را بسازید. پس بیایید به کامپوننتهای stateful و stateless وارد شویم.
کامپوننتهای stateless (یا نمایشی و تابعی)، کامپوننتهایی هستند که هیچ stateای ندارند (آیا نمیدانید state چیست؟ نگران نباشید، در ادامه آن را توضیح خواهم داد). این کامپوننتها برای نمایش استفاده میشوند. برای مثال این که میخواهید کامپوننت شما چه ظاهری داشته باشد.
یک کامپوننت، یک تابع JavaScript خالص است که یک prop را به عنوان آرگومان میگیرد و یک عنصر React را بر میگرداند (مثال بالا را ببینید). نام آن خودش را توضیح میدهد، این کامپوننت هیچ stateای ندارد. این کامپوننت هیچ متد lifecycleای ندارد (مانند متد componentDidMount یا... که شاید در طی روند تحقیق خود درباره React یا در آموزشهای آن شنیده باشید).
کامپوننتهای stateful (یا محفظه یا کلاس)، کامپوننتهایی هستند که state (یک منبع داده) و متدهای lifecycle (شما میتوانید از آنها برای ارسال یک فراخوانی API استفاده کنید) را دارند. این کامپوننت، یک کلاس JavaScript است که کامپوننت React شما را گسترش میدهد. یعنی React نمونههایی را از آن میسازد. React کلاس کامپوننت را در جهت استفاده از متدهای lifecycle، راهاندازی state و... راهاندازی میکند.
خب، حال شاید برایتان سوال باشد که کدام یک بهتر است، و کدام را انتخاب کنیم؟ اگر این سوال که «چگونه بخشهای منطقی را از بخشهای نمایشی جدا کنیم؟» در سرتان است، میتوانید به این سوال هم پاسخ دهید. بله، عجیب است که یک سوال پاسخ دیگری را میدهد، اما به زودی خواهید فهمید که چرا این حرف را زدم.
همانطور که شاید در آموزیهای دیگر React دیده باشید، این آموزشها از کلاس برای ساخت کامپوننتهای خود استفاده میکنند. آنها بخشهای منطقی و نمایشی در را بخشهای مشابهی قرار میدهند، که باعث میشود کامپوننت مورد نظر پیچیدهتر شود.
پس اگر میخواهید بخش منطقی را از کامپوننتهای نمایشی جدا کنید، کلاس کامپوننت برای چیزهای منطقی مانند دریافت دادهها از یک API یا تغییرات دادهها عالی است. در سمت دیگر اگر کامپوننت شما بر روی چیزهای نمایشی / تابعی متمرکز است، کامپوننت مورد نظر باید ظاهر خوبی داشته باشد.
به طور خلاصه، به نظر من از هر دو استفاده کنید. وقتی که به متدهای lifecycle و یا state نیاز دارید، از کلاس کامپوننت استفاده کرده، و برای نمایش هم از یک کامپوننت تابعی استفاده کنید.
بحث کامپوننتها در اینجا به پایان میرسد.
حال ما تصویری از نحوه نوشتن کامپوننتها را در ذهن داریم، اما من نحوه مدیریت دادهها در آنها را به شما نگفتهام. به نظر من کامپوننتها بدون داده هیچ کاربردی نخواهند داشت. پس ما نگاهی به نحوه مدیریت دادههای یک کامپوننت (مانند دریافت دادهها از یک API، تنظیم state و...) خواهیم داشت.
بیایید شروع کنیم.
Propها
Prop مخفف properties به معنای «ویژگی» بوده، و تنها منبع داده در کامپوننت ما میباشد. Prop میتواند برای انتقال داده به کامپوننتهای مختلف مورد استفاده قرار گیرد. صبر کنید! من میخواهم به جایی برگردم که به شما درباره کامپوننتهای نمایشی و کلاس توضیح دادم. من گفتم که از کامپوننتهای نمایشی برای مدیریت ظاهر کامپوننت خود، و از کامپوننتهای محفظه برای مدیریت دادهها استفاده کنید. صحیح!
پس prop چیزی است که میتوانیم از آن برای برقراری ارتباط بین این دو نوع کامپوننت استفاده کنیم. بله، شما میتوانید از propها برای منتقل کردن دادهها از یک کامپوننت محفظه به یک کامپوننت نمایشی استفاده کنید، که در آن، کامپوننت نمایشی مورد نظر view را با دادههای دینامیک شما رندر خواهد کرد. لطفا نگاهی به کد زیر داشته باشید، تا آن را بهتر درک کنید:
import {ButtonView} from './button.presentation';
class MyContainerComponent extends React.Component {
state={
text : 'Submit'
}
render() {
return (
<ButtonView btnText={this.state.text}/>
)}
}
(button.container.js file)
export const ButtonView=({btnText})=>(
<div>
<button className="btn btn-info btn-lg">{btnText}</button>
</div>
)
(button.presentation.js file)
به مانند راه بالا (استفاده از propها - btnText)، شما میتوانید بخش منطقی را از بخش نمایشی جدا کنید. ویژگی دیگر propها این است که آنها read only، یا به عبارتی دیگر غیر قابل جهش هستند. آنها قرار نیست داخل کامپوننتی که به آنها منتقل شده است، تغییر کنند. جریان داده آنها هم یک طرفه است، که به ما اتصال داده یک طرفه را میدهد (برخلاف Angular).
State
همانطور که گفتم، propها غیر قابل جهش میباشند، اما state هم برای دادههای قابل جهش است. اینها دادههایی هستند که در پاسخ به برخی رویدادهای خاص، تغییر خواهند کرد. پس حتی اگر میخواهید مقدار دادههای خود را تغییر دهید، آن را در state ذخیره کنید. Stateها آبجکتهایی هستند که دادههای کامپوننت شما را ذخیره میکنند. برای داشتن دید بهتری نسبت به نحوه تعریف state و استفاده از آن، این مثال را ببینید:
class LoginContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
userName: "",
};
}
onFilluserName = event => {
this.setState({
userName: event.target.value,
});
render() {
return (
<div>
<input
value={this.state.userName}
onChange={this.onFilluserName}
</div>
);
}
}
از روی مثال بالا میتوانید ببینید که state نمایانگر آبجکتهایی است که دادههای کامپوننت شما در آن ذخیره میشوند. این آبجکتها داخل یک constructor راهاندازی میشوند. شما میتوانید به state با استفاده از this.state دسترسی داشته باشید. این راه استفاده از state برای رندر کردن دادهها داخل کامپوننت خود است.
اما من به شما گفتم چیزی که state را تبدیل به قلب کامپوننت شما میکند، رفتار غیر قابل جهش آن است. بله، حال نکته در اینجاست که ما چگونه میتوانیم ویژگی state را تغییر دهیم؟ پاسخ، استفاده از this.useState میباشد (لطفا به مثال بالا نگاهی داشته باشید). ما با استفاده از this.useState، مقدار دادههای خود را وقتی که کاربر تایپ میکند، تغییر دادهایم.
به طور خلاصه، propها و state هر دو منابع داده هستند، اما نحوه استفاده و رفتار آنها متفاوت است. هر زمان که باید دادههایی را مدیریت کنید و این دادهها شاید تغییر کنند، از state استفاده کنید. در غیر این صورت هم prop یک انتخاب خوب است.
مبحث پایههای دنیای React هم در اینجا به پایان میرسد. امیدوارم حال درک بهتری از آنها داشته باشید.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید