حالا که همه مسائل مربوط به محتویات همبرگر و قیمت آن را از طریق 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 برایم باز شود:
همه چیز صحیح است؛ از هر کدام از مواد همبرگر 1 عدد ثبت و قیمت نهایی 6.90 شده است. بنابراین روی Continue کلیک کنید تا صفحه بعدی را بررسی کنیم:
شکل همبرگر کاملا سالم و دقیقا طبق سفارش ثبت شده ما است (اگر یادتان باشد این همبرگر یک همبرگر تصادفی و نمایشی نیست بلکه خودمان آن را طوری برنامه ریزی کرده بودیم که دقیقا بر اساس سفارش کاربر محاسبه شود). باز هم روی Continue کلیک کنید تا جلوتر برویم:
با کلیک روی Continue فرم ما نمایش داده می شود بنابراین کدها سالم هستند. مهم نیست چه اطلاعاتی در این فرم وارد می کنیم بنابراین من داده هایی جعلی و تصادفی را برای تست وارد کرده ام (البته تا حدی که با کدهای اعتبار سنجی فرم ما مطابقت داشته باشند). در نهایت روی ORDER کلیک کنید تا سفارش ثبت شود.
توجه داشته باشید که برای صحیح اجرا شدن این قسمت باید اینترنت شما فعال بوده و ابزار دور زدن تحریم نیز داشته باشید (به دلیل محدودیت های firebase). پس از کلیک روی ORDER باید به صفحه اصلی ثبت سفارش redirect شوید که دقیقا همین اتفاق نیز می افتد. حالا برای تست کردن کدها به firebase بروید و به قسمت orders و سپس orderData نگاهی بیندازید:
اطلاعات وارد شده در فرم را در این قسمت مشاهده می کنیم. اگر چنین اطلاعاتی را مشاهده نکردید احتمالا از ابزار دور زدن تحریم در هنگام ثبت سفارش استفاده نکرده بودید و یا اینکه قسمتی از کدهایتان اشکال دارد، آن ها را دوباره چک کنید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.