تصحیح کامپوننت‌های Checkout و ContactData

?How to Correct Checkout and ContactData Components

22 بهمن 1399
تصحیح کامپوننت های Checkout و ContactData

حالا که همه مسائل مربوط به محتویات همبرگر و قیمت آن را از طریق state سراسری و redux مدیریت می کنیم بهتر است بقیه کامپوننت های اصلی یعنی checkout و ContactData را نیز تصحیح کنیم. اگر یادتان باشد برای پاس داده داده ها به checkout مجبور به استفاده از query param ها بودیم که فرآیندی پیچیده و بیهوده بود اما حالا که redux داریم می توانیم به سادگی از state سراسری استفاده کنیم!

برای شروع کار وارد BurgerBuilder.js شوید و متد purchaseContinueHandler را به شکل زیر ویرایش کنید:

    purchaseContinueHandler = () => {
        this.props.history.push('/checkout');
    }

در واقع تمام کدهای query param را حذف کرده ام و دستور push را هم مستقیما به checkout داده ام. دیگر نیازی به ارسال هیچ داده ای از سمت این کامپوننت نداریم. در مرحله بعد وارد کامپوننت Checkout.js می شویم و به componentWillMount نگاهی می اندازیم:

state = {
    ingredients: null,
    price: 0
}

componentWillMount() {
    const query = new URLSearchParams(this.props.location.search);
    const ingredients = {};
    let price = 0;
    for (let param of query.entries()) {
        // ['salad', '1']
        if (param[0] === 'price') {
            price = param[1];
        } else {
            ingredients[param[0]] = +param[1];
        }
    }
    this.setState({ ingredients: ingredients, totalPrice: price });
}

ما دیگر نیازی به دریافت مقادیر از طریق query param ها نداریم. همچنین از آنجایی که مقداری را با query param ها نمی گیریم نیازی به دستور setState نیز نداریم و نهایتا می توانیم کل componentWillMount را حذف کنیم. پس از حذف componentWillMount باید state درون برنامه را نیز حذف کنیم چرا که حالا از State سراسری استفاده می کنیم و دیگر نیازی به آن نداریم.

در مرحله بعد که می خواهیم از state سراسری استفاده کنیم باید connect را وارد فایل checkout.js کنیم بنابراین:

import { connect } from 'react-redux';

سپس به انتهای فایل checkout.js برویم و مثل همیشه mapStateToProps را اضافه می کنیم:

const mapStateToProps = state => {
    return {
        ings: state.ingredients,
        price: state.totalPrice
    }
};

در نهایت با پاس دادن mapStateToProps چرخه استفاده از redux را کامل می کنیم:

export default connect(mapStateToProps)(Checkout);

حالا که کامپوننت ما به state سراسری متصل شده است، می توانیم در CheckoutSummary از مقادیر State استفاده کنیم و هر جا که this.state.ingredients وجود داشت، آن را به this.props.ings تبدیل کنیم البته قبل از ادامه کار احتمالا یادتان هست که برای بارگذاری contactData از یک حقه استفاده کرده بودیم:

render() {
    return (
        <div>
            <CheckoutSummary
                ingredients={this.state.ingredients}
                checkoutCancelled={this.checkoutCancelledHandler}
                checkoutContinued={this.checkoutContinuedHandler} />
            <Route
                path={this.props.match.path + '/contact-data'}
                render={(props) => (<ContactData ingredients={this.state.ingredients} price={this.state.totalPrice} {...props} />)} />
        </div>
    );
}

بله! به آن یک prop با نام render دادیم بودیم و کل contactData را به همراه prop هایش را درون آن قرار دادیم اما حالا که از redux استفاده می کنیم نیازی به انجام این کارها نیست و در واقع نیازی به دسترسی به price هم نداریم! بنابراین می توانیم کدهای بالا را به شکل زیر ویرایش کنیم:

render() {
    return (
        <div>
            <CheckoutSummary
                ingredients={this.props.ings}
                checkoutCancelled={this.checkoutCancelledHandler}
                checkoutContinued={this.checkoutContinuedHandler} />
            <Route
                path={this.props.match.path + '/contact-data'}
                component={ContactData} />
        </div>
    );
}

ابتدا ingredients درون CheckoutSummary را تصحیح کرده ام و سپس به جای استفاده از render در Route از component استفاده کرده ایم تا به راحتی به contactData برویم. بر این اساس دیگر نیازی به price درون mapStateToProps نداریم:

const mapStateToProps = state => {
    return {
        ings: state.ingredients
    }
};

حالا به ContactData.js می رویم تا آن را نیز تصحیح کنیم. ما در این کامپوننت نیز از ingerdients استفاده می کنیم مثلا:

const order = {
    ingredients: this.props.ingredients,
    price: this.props.price,
    orderData: formData
}

حالا می توانیم همین فایل را نیز به redux متصل کنیم. برای این کار ابتدا connect را از پکیج redux وارد کنید:

import { connect } from 'react-redux';

سپس مثل همیشه mapStateToProps را تعریف می کنیم تا موارد مورد نیاز درون state خود را از آن بگیریم:

const mapStateToProps = state => {
    return {
        ings: state.ingredients,
        price: state.totalPrice
    }
};

و در نهایت این مقادیر و کامپوننت خود را با connect به redux متصل می کنیم:

export default connect(mapStateToProps)(ContactData);

در مرحله بعد هر جایی که درون این کامپوننت از props.ingredients استفاده کرده است را به props.ings تغییر می دهیم چرا که قبلا از query param ها استفاده می کردیم و آن ها به صورت prop به ما ارسال می شدند اما دیگری نیازی به ارسال آن ها نداریم:

const order = {
    ingredients: this.props.ings,
    price: this.props.price,
    orderData: formData
}

مقدار props.price تغییری نخواهد کرد چرا که ما هنگام وارد کردن خصوصیت قیمت از redux، نام price را انتخاب کرده ایم بنابراین همه چیز صحیح است.

حالا تمام کدها را ذخیره کرده و به مرورگر بروید. در این قسمت هر نوع محتویاتی را که می خواهید اضافه کنید تا صحت کدها را تست کنیم:

انتخاب مخلفات و مواد همبرگر
انتخاب مخلفات و مواد همبرگر

همانطور که می بینید من از هر کدام از مواد همبرگر 1 عدد را انتخاب کرده ام و قیمت همبرگر من 6.90 دلار شده است. حالا قدم مهم این است که در صفحه modal ما و هنگام باز شدن خلاصه سفارش (OrderSummary) همه چیز دقیقا با هنگام انتخاب مواد اولیه یکی باشد. من روی دکمه ORDER NOW کلیک می کنم تا modal برایم باز شود:

چک کردن modal باز شده برای تطبیق سفارش
چک کردن modal باز شده برای تطبیق سفارش

همه چیز صحیح است؛ از هر کدام از مواد همبرگر 1 عدد ثبت و قیمت نهایی 6.90 شده است. بنابراین روی Continue کلیک کنید تا صفحه بعدی را بررسی کنیم:

نمایش سفارش به صورت گرافیکی
نمایش سفارش به صورت گرافیکی

شکل همبرگر کاملا سالم و دقیقا طبق سفارش ثبت شده ما است (اگر یادتان باشد این همبرگر یک همبرگر تصادفی و نمایشی نیست بلکه خودمان آن را طوری برنامه ریزی کرده بودیم که دقیقا بر اساس سفارش کاربر محاسبه شود). باز هم روی Continue کلیک کنید تا جلوتر برویم:

پر کردن فرم با داده های تستی و دلخواه
پر کردن فرم با داده های تستی و دلخواه

با کلیک روی Continue فرم ما نمایش داده می شود بنابراین کدها سالم هستند. مهم نیست چه اطلاعاتی در این فرم وارد می کنیم بنابراین من داده هایی جعلی و تصادفی را برای تست وارد کرده ام (البته تا حدی که با کدهای اعتبار سنجی فرم ما مطابقت داشته باشند). در نهایت روی ORDER کلیک کنید تا سفارش ثبت شود.

توجه داشته باشید که برای صحیح اجرا شدن این قسمت باید اینترنت شما فعال بوده و ابزار دور زدن تحریم نیز داشته باشید (به دلیل محدودیت های firebase). پس از کلیک روی ORDER باید به صفحه اصلی ثبت سفارش redirect شوید که دقیقا همین اتفاق نیز می افتد. حالا برای تست کردن کدها به firebase بروید و به قسمت orders و سپس orderData نگاهی بیندازید:

چک کردن موارد ثبت شده در پایگاه داده ی Firebase
چک کردن موارد ثبت شده در پایگاه داده Firebase

اطلاعات وارد شده در فرم را در این قسمت مشاهده می کنیم. اگر چنین اطلاعاتی را مشاهده نکردید احتمالا از ابزار دور زدن تحریم در هنگام ثبت سفارش استفاده نکرده بودید و یا اینکه قسمتی از کدهایتان اشکال دارد، آن ها را دوباره چک کنید.

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

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