در این درس یاد می گیریم که چطور کامپوننت هایی با قابلیت استفاده مجدد ایجاد کنیم و بتوانیم این کامپوننت ها را با سایر تیم ها و یا اپلیکیشن ها به اشتراک بگذاریم. امروز وارد هفته دوم آموزش می شویم و تا به اینجا با ویژگی های اصلی ری اکت مثل prop، state، چرخه حیات، jsx و ... آشنا شدید.
در این درس می خواهیم کمی با نحوه مستندسازی و پکیج بندی کردن یا به عبارت دیگر اعتبارسنجی کامپوننت ها آشنا شویم.
همان طور که در قسمت های قبلی دیدید ما از props ها به دفعات در کامپوننت های مان استفاده کردیم. در اکثر موارد انتظار داریم که یک مقدار از نوع داده پایه ای و یا مجموعه ای (مثل آبجکت ها یا یک رشته) به این propها نسبت داده شوند.
ری اکت یک متد برای تعریف و اعتبارسنجی این نوع داده ها دارد که به ما اجازه می دهد تا به آسانی یک api برای کامپوننت را نمایش دهیم.
این قابلیت نه تنها برای نوشتن مستندات خوب است، بلکه برای ساخت کامپوننت هایی با قابلیت استفاده مجدد، امکانات زیادی را در اختیار ما می گذارد.
آبجکت prop-type مجموعه ای از نوع داده های مختلف است که می توانیم برای تعریف نوع داده هایی که propهای یک کامپوننت باید داشته باشند، استفاده کنیم و این ها را با استفاده از متد propType در یک کلاس ES6 تعریف کنیم.
class Clock extends React.Component { // ... } Clock.propTypes = { // key is the name of the prop and // value is the PropType }
در داخل این prop، یک آبجکت تعریف می کنیم که پروپرتی اول یا کلید این آبجکت همان نام prop است و پروپرتی دوم یا مقدار آن هم همان نوع یا نوع هایی است که این prop باید داشته باشد.
برای مثال کامپوننت Header که در چند درس قبلی ساختیم، یک پروپرتی به نام title می گیرد و نوع آن هم انتظار داریم رشته ای باشد. برای تعریف یک نوع داده رشته ای برای این پروپرتی مطابق زیر عمل می کنیم:
ابتدا پکیج propType را از پکیج prop-types وارد برنامه می کنیم (import):
import PropTypes from 'prop-types'
ری اکت نوع داده های زیادی دارد که می توان آنها را انتخاب کرد و حتی به ما اجازه می دهد تا نوع داده های سفارشی هم ایجاد کنیم. در زیر به لیست کاملی از نوع داده ها نگاهی می اندازیم:
ری اکت چند نوع داده پایه ای دارد که می توانیم از آنها در برنامه مان استفاده کنیم.
همچنین این امکان وجود دارد که یک نوع داده anything هم برای prop انتخاب کنیم، در این صورت مقدار توسط propType.node نمایش داده می شود.
Clock.propTypes = { title: PropTypes.string, count: PropTypes.number, isOn: PropTypes.bool, onDisplay: PropTypes.func, symbol: PropTypes.symbol, user: PropTypes.object, name: PropTypes.node }
در قسمت های قبلی درباره برقراری ارتباط از کامپوننت والد به فرزند توسط prop صحبت کردیم. حال برای ارتباط از یک کامپوننت فرزند به والد از یک تابع استفاده می کنیم. معمولا از این الگو برای مواقعی بهره می بریم که بخواهیم از طریق کامپوننت فرزند، کامپوننت والد را مدیریت کنیم.
ما می توانیم کالکشن های iterable (کالکشن هایی که توسط یک حلقه تکرار می توان به عناصر آن دسترسی پیدا کرد) را هم به prop ها پاس بدهیم. در قسمت های قبلی این قابلیت را با ارسال یک آرایه به اکتیویتی مان نشان دادیم. برای تعریف یک نوع داده آرایه ای برای prop کامپوننت، از دستور propTypes.array استفاده می کنیم. همچنین می توانیم آرایه هایی داشته باشیم که عناصر آن آبجکت هایی از یک نوع مشخص باشند و اینکار را با دستور propTypes.arrayOf
انجام می دهیم:
همچنین می توانیم آبجکتی تعریف کنیم که پروپرتی های داخل آن از نوع داده های مختلفی باشند و اینکار را با دستور propTypes.oneOfType
انجام می دهیم.
Clock.propTypes = { counts: PropTypes.array, users: PropTypes.arrayOf(PropTypes.object), alarmColor: PropTypes.oneOf(['red', 'blue']), description: PropTypes.oneOfType([ PropTypes.string, PropTypes.instanceOf(Title) ]), }
همچنین می توانیم نوع داده ای ایجاد کنیم که نیاز به یک مقدار از نوع نمونه ای از یک کلاس داشته باشد.
Clock.propTypes = { basicObject: PropTypes.object, numbers: PropTypes .objectOf(PropTypes.numbers), messages: PropTypes .instanceOf(Message), contactList: PropTypes.shape({ name: PropTypes.string, phone: PropTypes.string, }) }
ما می توانیم عناصر ری اکت را از یک کامپوننت والد به کامپوننت فرزند ارسال کنیم. این قابلیت به ما امکان ساخت قالب ها و سفارشی کردن آنها را می دهد.
Clock.propTypes = { displayEle: PropTypes.element }
هنگام استفاده از element، ری اکت انتظار دارد که یک کامپوننت فرزند را به عنوان پروپرتی دریافت کند. همچنین به یاد داشته باشید که نمی توانیم بیش از یک کامپوننت را به آن ارسال کنیم.
// Invalid for elements <Clock displayElement={ <div>Name</div> <div>Age</div> }></Clock> // Valid <Clock displayElement={ <div> <div>Name</div> <div>Age</div> </div> }></Clock>
شما می توانید توسط isRequired کاری کنید تا فراهم کردن یک مقدار برای پروپرتی ها اجباری باشد.
Clock.propTypes = { title: PropTypes.name.isRequired, }
اجباری کردن مقدار برای یک پروپرتی در مواقعی مفید است که کامپوننت وابسته به مقداری است که باید توسط کامپوننت والد و از طریق یک prop دریافت کند و در غیراینصورت کامپوننت کار نخواهد کرد.
در انتها می توان از یک تابع برای تعریف انوع داده های سفارشی استفاده کرد. برای انجام اینکار از یک prop و یا آرایه های اعتبارسنجی استفاده می کنیم. تنها پیش نیاز برای تابع سفارشی این است که اگر اعتبارسنجی به آن پاس داده نشود، باید یک آبجکت error برگردانیم.
UserLink.propTypes = { userWithName: (props, propName, componentName) => { if (!props[propName] || !props[propName].name) { return new Error( "Invalid " + propName + ": No name property defined for component " + componentName ) } } }
گاهی اوقات می خواهیم یک مقدار پیش فرض برای یک prop تنظیم کنیم. برای مثال، درکامپوننت <Header/> می توان کاری کرد که ارسال یک مقدار به پروپرتی title آن الزامی نباشد. اگر مقداری پاس داده نشود، ما از یک مقدار پیش فرض برای نمایش عنوان این کامپوننت استفاده می کنیم.
برای تنظیم یک مقدار پیش فرض برای یک prop باید یک آبجکت را به defaultProps
نسبت دهیم که پروپرتی این ابجکت مقدار پیش فرض را مشخص خواهد کرد
Header.defaultProps = { title: 'Github activity' }
امروز به امکانات ری اکت برای مستندسازی نگاهی انداختیم. بهتر است همیشه توسط خصیصه های propType و defaultProps بتوانیم کامپوننت هایی با قابلیت استفاده مجدد را ایجاد کنیم. این قابلیت ها علاوه بر امکان به اشتراک گذاری کامپوننت ها بین توسعه دهندگان، به مستندسازی و اعتبارسنجی برنامه هم کمک زیادی می کند.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.