با پایان فصل 8 باید به پروژه ی همبرگر ساز برگردیم و Routing را به آن اضافه کنیم. در حال حاضر با کلیک روی دکمه ی ثبت سفارش مستقیما سفارش را در پایگاه داده ی Firebase ذخیره می کنیم اما هدف اصلی من این است که با کلیک روی ثبت سفارش به صفحه ی checkout برویم. از آنجایی که این صفحه را نداریم باید آن را بسازیم. من می خواهم آن را درون پوشه ی containers قرار بدهم چرا که این کامپوننت قرار است State خودش را داشته باشد و آن را به بقیه پاس بدهد بنابراین درون پوشه ی containers یک پوشه ی دیگر به نام Checkout بسازید که حاوی فایلی به نام Checkout.js باشد. از آنجایی که این فایل یک کامپوننت کلاس محور است. برای شروع باید این کدها را بنویسیم:
import React, { Component } from 'react'; class Checkout extends Component { } export default Checkout;
کار صفحه ی checkout نمایش خلاصه ای از سفارش است تا کاربر آن را چک کرده و پس از اطمینان سفارش را نهایی کند. در این قسمت باید یک دکمه برای کنسل کردن سفارش نیز داشته باشیم تا اگر کاربر نظرش را تغییر کرد بتواند به همبرگر ساز برگردد و سفارش را تغییر دهد. بهتر است این موارد را به صورت کامپوننت طراحی کنیم بنابراین به پوشه ی components بروید و یک پوشه ی دیگر به نام order ایجاد کنید. سپس درون این پوشه یک پوشه ی دیگر به نام CheckoutSummary ایجاد کنید که حاوی فایل هایی به نام های CheckoutSummary.js و CheckoutSummary.module.css باشد.
محتوای فایل CheckoutSummary.js در ابتدا بدین شکل خواهد بود:
import React from 'react'; const checkoutSummary = (props) => { } export default checkoutSummary;
حالا باید کدهای JSX را درون این قسمت بنویسیم. طراحی این صفحه را ساده انجام می دهیم:
const checkoutSummary = (props) => { return ( <div> <h1>We hope it tastes well!</h1> <div> </div> </div> ); }
در این کد ابتدا یک div داریم تا کار عنصر ریشه ای را انجام دهد. سپس h1 را داریم که به کاربر می گوییم امیدواریم همبرگر خوش مزه باشد و در نهایت یک div را اضافه کرده ایم که قرار است کامپوننت همبرگر را در آن نمایش دهیم. بله همان شکلی که در صفحه ی اول پروژه داریم. اما برای تعیین اندازه ی آن باید از استایل های inline استفاده کنیم:
<div> <h1>We hope it tastes well!</h1> <div style={{ width: '300px', height: '300px', margin: 'auto' }}> </div> </div>
با مشخص کردن طول و عرض 300 پیکسلی، همبرگر را کوچک تر کرده ایم تا صفحه مان را به هم نریزد. برای استفاده از خود همبرگر نیز نیازی به کدنویسی دوباره نیست بلکه کافی است آن را درون این فایل import کنیم:
import Burger from '../../Burger/Burger';
حالا می توانیم آن را درون div مورد نظرش قرار دهیم:
<div style={{ width: '300px', height: '300px', margin: 'auto' }}> <Burger /> </div>
قبل از ادامه باید نگاهی به کامپوننت Burger بیندازیم. قسمتی از کدهای آن به شکل زیر است:
const burger = (props) => { let transformedIngredients = Object.keys(props.ingredients).map(igKey => {
همانطور که می بینیم این کامپوننت به یک prop به نام ingredients نیاز دارد بنابراین ما فرض می کنیم که CheckoutSummary نیز این prop را دریافت می کند و آن را به Burger پاس می دهیم:
return ( <div> <h1>We hope it tastes well!</h1> <div style={{ width: '300px', height: '300px', margin: 'auto' }}> <Burger ingredients={props.ingredients} /> </div> </div> );
حالا برای ایجاد دکمه ی کنسل کردن سفارش از همان کامپوننت Button خودمان استفاده کرده و آن را درون پروژه import می کنیم:
import Button from '../../UI/Button/Button';
اگر یادتان باشد این کامپوننت دو کد مختلف CSS داشت:
.Success { color: #5C9210; } .Danger { color: #944317; }
این دو کلاس باید به عنوان یک prop (به نام btnType) به button پاس داده شوند بنابراین ما هم آن را پاس می دهیم:
return ( <div> <h1>We hope it tastes well!</h1> <div style={{ width: '300px', height: '300px', margin: 'auto' }}> <Burger ingredients={props.ingredients} /> </div> <Button btnType="Danger"> CANCEL </Button> <Button btnType="Success"> CONTINUE </Button> </div> );
دکمه ی CANCEL سفارش را لغو و دکمه ی CONTINUEسفارش را ثبت خواهد کرد. یکی دیگر از prop های مورد نیاز این کامپوننت clicked نام داشت که مشخص می کرد هنگام کلیک شدن روی این دکمه چه اتفاقی بیفتد. برای آنکه یادمان نرود بهتر است آن ها را بدون کدهایشان اضافه کنیم:
<Button btnType="Danger" clicked> CANCEL </Button> <Button btnType="Success" clicked> CONTINUE </Button>
فعلا آن ها را به همین شکل رها می کنیم تا بعدا برگردیم و کدهای clicked را تکمیل کنیم. حالا باید یک className به div ریشه ای خود بدهیم. ابتدا درون فایل CheckoutSummary.module.css کدهای زیر را اضافه کنید:
.CheckoutSummary { text-align: center; width: 80%; margin: auto; } @media (min-width: 600px) { .CheckoutSummary { width: 500px; } }
حالا کلاس بالا را وارد پروژه مان می کنیم:
import classes from './CheckoutSummary.module.css';
و سپس آن را به div می دهیم:
const checkoutSummary = (props) => { return ( <div className={classes.CheckoutSummary}> // بقیه ی کدها //
حالا به فایل Checkout.js می رویم و این کامپوننت را در آنجا import می کنیم:
import CheckoutSummary from '../../components/Order/CheckoutSummary/CheckoutSummary';
سپس این کامپوننت را درون کدهای JSX همین فایل قرار می دهیم:
class Checkout extends Component { render() { return ( <div> <CheckoutSummary /> </div> ); } }
مشکل این جاست که CheckoutSummary به یک prop به نام ingredients نیاز دارد که آن را به Burger پاس بدهد. از کجا به این prop دسترسی پیدا کنیم؟ فعلا محتوای ingredients را به صورت دستی و جعلی قرار می دهیم تا بعدا وارد این موضوع شویم:
class Checkout extends Component { state = { ingredients: { salad: 1, meat: 1, cheese: 1, bacon: 1 } } render() { return ( <div> <CheckoutSummary ingredients={this.state.ingredients} /> </div> ); } }
ابتدا یک State ساخته ایم که داده های جعلی ما را نگه می دارد، سپس آن را از درون ingredients روی <CheckoutSummary> قرار داده ایم. بعدا با استفاده از Routing این prop ها را پاس خواهیم داد.
در مرحله ی بعد وارد App.js شوید و کامپوننت Checkout را در آن import کنید:
import Checkout from './containers/Checkout/Checkout';
فعلا برای اینکه ببینیم برنامه چه ظاهری دارد آن را به صورت دستی وارد قسمت JSX می کنم اما بعدا باید آن را با Routing و به صورت شرطی بارگذاری کنیم:
return ( <div> <Layout> <BurgerBuilder /> <Checkout /> </Layout> </div> );
حالا فایل ها را ذخیره کرده و به مرورگر بروید. متاسفانه می بینیم که همبرگر ما دقیقا در وسط صفحه قرار نگرفته است:
برای تصحیح آن باید به CheckoutSummary.js برگردیم. اگر مقدار width را در استایل های inline روی 100 درصد بگذاریم این مشکل حل خواهد شد. همچنین فعلا height را حذف می کنیم تا روی دستگاه های کوچک تر (موبایل و تبلت) مشکلی نداشته باشیم:
<div style={{ width: '100%', margin: 'auto' }}>
در قسمت بعد می خواهیم Routing را به پروژه اضافه کرده و کاری کنیم که با کلیک روی CONTINUE (هنگام ثبت سفارش) سفارش به Firebase نرود بلکه به صفحه ی Checkout برویم.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.