اعتبارسنجی با propType و نمایش همبرگر

Validation with propType and Hamburger Display

23 بهمن 1399
اعتبار سنجی با propType و نمایش همبرگر

در قسمت قبل کامپوننت Layout و چند کامپوننت دیگر را کدنویسی کردیم. در این قسمت می خواهیم برای props یک نوع اعتبارسنجی ایجاد کنیم تا مطمئن شویم prop های خاص ما حتما پاس داده می شوند (یعنی فردی نتواند سفارشی را بدون هیچ کدام از مواد اولیه بخرد، مشخصا خرید «هیچ» یک عملیات غیرمنطقی است که نباید در برنامه ما وجود داشته باشد). برای اعتبارسنجی prop از همان پکیجی استفاده می کنیم که در فصل قبل در موردش صحبت کردیم؛ پکیج propType.

ابتدا باید این پکیج را در پروژه فعلی نصب کنیم بنابراین می گوییم:

npm install --save prop-type

حالا وارد فایل BurgerIngredient.js می شویم و در آنجا prop-type را import می کنیم تا بتوانیم از آن استفاده کنیم:

import PropTypes from 'prop-types';

 شما می توانید از propTypes هم روی کامپوننت های کاربردی و هم روی کامپوننت های کلاس-محور استفاده کنید اما من ترجیح می دهم در این قسمت کامپوننت BurgerIngredient را تبدیل به یک کامپوننت کلاس محور کنم تا تبدیل کردن کامپوننت ها را هم تمرین کرده باشیم:

ابتدا component را import کنید:

import React, { Component } from 'react';

سپس burgerIngredient را با کلیدواژه class می نویسیم تا شیء component را extend کند:

class BurgerIngredient extends Component {

حالا درون بدنه BurgerIngredient باید متد render را بنویسیم (تمام کامپوننت های کلاس-محور به آن نیاز دارند) حالا می توانیم کدهای Switch از جلسه قبل را درون آن قرار دهیم:

class BurgerIngredient extends Component {

    render() {
        let ingredient = null;

        switch (props.type) {
            case ('bread-bottom'):
                ingredient = <div className={classes.BreadBottom}></div>;
                break;
            case ('bread-top'):
                ingredient = (
                    <div className={classes.BreadTop}>
                        <div className={classes.Seeds1}></div>
                        <div className={classes.Seeds2}></div>
                    </div>
                );
                break;
            case ('meat'):
                ingredient = <div className={classes.Meat}></div>;
                break;
            case ('cheese'):
                ingredient = <div className={classes.Cheese}></div>;
                break;
            case ('bacon'):
                ingredient = <div className={classes.Bacon}></div>;
                break;
            case ('salad'):
                ingredient = <div className={classes.Salad}></div>;
                break;
            default:
                ingredient = null;
        }
        return ingredient;
    }

}

همچنین به دلیل پیروی از قرارداد های نام گذاری، نام کامپوننت را با حرف بزرگ شروع کرده ام (BurgerIngredient)، شما هم اگر این کار را کرده اید باید در پایین صفحه و کنار دستور export حرف b را به B تبدیل کنید (دستور export به کوچکی و بزرگی حروف حساس است).

حالا اگر به کدمان نگاه کنیم هنوز یک مشکل را پیدا می کنیم. در کامپوننت های کلاس محور props.type کار نمیکند و به جای آن باید بگوییم this.props.type بنابراین:

 switch (this.props.type) {

حالا می توانیم برای کامپوننت خود propTypes تعیین کنیم. بالاتر از دستور export و خارج از خود کامپوننت می نویسیم:

BurgerIngredient.propTypes = {
    type: PropTypes.string.isRequired
}

یعنی ابتدا نام کلاس را می آوریم، سپس propTypes (با p کوچک و دقیقا به همین شکل) را صدا می زنیم. باید آن را برابر با یک شیء جاوا اسکریپتی قرار دهیم و در داخل آن برای یکی از props هایی که به این کامپوننت پاس داده خواهد شد (type) شروطی تعیین می کنیم. ابتدا باید نام import شده PropTypes را صدا بزنید (از آنجایی که من در هنگام import کردن آن را به شکل PropTypes نوشتم اینجا هم باید آن را به همین شکل بنویسم) و با اضافه کردن string اعلام میکنم که این prop باید یک رشته باشد. در آخر یک شرط دیگر هم به آن چسبانده ام که می گوید isRequired یعنی این prop اجباری است و حتما باید پاس داده شود.

هنوز نمی توانیم این کد را تست کنیم چرا که هنوز prop پاس داده شده (یعنی type) را ننوشته ایم. بنابراین به فایل Burger.js بروید تا کدنویسی این قسمت را انجام دهیم.

کدنویسی Burger.js

فعلا برای سادگی کار فقط مقداری JSX برمی گردانیم، بنابراین ابتدا بدنه اصلی را می نویسیم:

import React from 'react';

const burger = (props) => {
    return (
        <div></div>
    );
}

export default burger;

ما از قصد از یک div ریشه ای استفاده کرده ایم چرا که کامپوننت burger قرار است یک wrapper (در بردارنده) برای کامپوننت های دیگر درونش باشد و می خواهیم همه چیز در یک div قرار بگیرد. حالا باید استایل هایش را بنویسیم تا طول و عرض همبرگر را مشخص کنیم، بنابراین یک فایل جدید به نام burger.module.css را ایجاد کرده و کلاس زیر را در آن می نویسیم:

.Burger {
    width: 100%;
    margin: auto;
    height: 250px;
    overflow: scroll;
    text-align: center;
    font-weight: bold;
    font-size: 1.2rem;
}

این کلاس ها بر اساس سلیقه ماست و شما می توانید آن ها را تغییر دهید. این کلاس مخصوص دستگاه های موبایل است بنابراین باید برای دستگاه های بزرگتر مانند لپتاپ ها و دستگاه های درازتر مانند گوشی های دراز نیز استایل بنویسیم:

@media (min-width: 500px) and (min-height: 400px) {
    .Burger {
        width: 350px;
        height: 300px;
    }
}

@media (min-width: 500px) and (min-height: 401px) {
    .Burger {
        width: 450px;
        height: 400px;
    }
}

@media (min-width: 1000px) and (min-height: 700px) {
    .Burger {
        width: 700px;
        height: 600px;
    }
}

این media query ها بر اساس سلیقه ما نوشته شده و سعی کرده ایم که کاری کنیم تا همبرگر در تمام سایزهای مختلف به خوبی نمایش داده شود، مانند بقیه کدهای CSS شما می توانید بر اساس سلیقه خود آن را تغییر دهید. در آخر باید کلاس CSS خود را وارد فایل Burger.js کنیم:

import classes from './burger.module.css';

const burger = (props) => {
    return (
        <div className={classes.Burger}>
            
        </div>
    );
}

حالا که استایل دهی را انجام داده ایم باید مواد اولیه (ingredient) را درون این div ریشه ای قرار دهیم بنابراین ابتدا آن را وارد می کنیم:

import BurgerIngredient from './BurgerIngredient/BurgerIngredient';

سپس آن را به همراه prop اش درون div قرار می دهیم:

const burger = (props) => {
    return (
        <div className={classes.Burger}>
            <BurgerIngredient type="bread-top" />
            <BurgerIngredient type="cheese" />
            <BurgerIngredient type="meat" />
            <BurgerIngredient type="bread-bottom" />
        </div>
    );
}

از آنجایی که هنوز هیچ مکانیسمی برای دریافت ورودی کاربر نداریم، به صورت دستی برخی از مواد اولیه را اضافه کرده ام. اگر یادتان باشد در propTypes تعریف کرده بودیم که type باید همیشه رشته باشد به همین دلیل اینجا هم آن را به صورت رشته نوشته ایم.

کار این کامپوننت نیز تمام شده است و حالا نوبت render کردن آن است. برای این کار به فایل BurgerBuilder.js بروید و به جای div ساده درون آن، همبرگر خودمان را قرار دهیم. در حال حاضر محتویات این فایل به شکل زیر است:

class BurgerBuilder extends Component {
    render() {
        return (
            <Aux>
                <div>Burger</div>
                <div>Build Controls</div>
            </Aux>
        );
    }
}

ما باید ابتدا همبرگر خود را import کنیم:

import Burger from '../../components/Burger/Burger';

 و سپس کدهای درون BurgerBuilder را به شکل زیر در بیاوریم:

class BurgerBuilder extends Component {
    render() {
        return (
            <Aux>
                <Burger />
                <div>Build Controls</div>
            </Aux>
        );
    }
}

تمام فایل ها را ذخیره کرده و به مرورگر بروید. باید تصویر همبرگر را درون مرورگر مشاهده کنید:

همبرگر نمایش داده شده در مرورگر
همبرگر نمایش داده شده در مرورگر

در صورتی که در گوشه های همبرگر اسکرول بار را مشاهده می کنید، می توانید قسمت overflow در فایل burger.module.css را حذف کنید. در قسمت های بعدی می خواهیم کاری کنیم که کاربر تعیین کننده محتوای همبرگر باشد نه اینکه خودمان به صورت دستی کدهایش را بنویسیم.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری دوره جامع آموزش ری اکت توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.