اگر از قسمت قبل به یاد داشته باشید ما کدهای دکمه های CANCEL و CONTINUE را تکمیل نکردیم:
<Button btnType="Danger" clicked> CANCEL </Button> <Button btnType="Success" clicked> CONTINUE </Button>
در حال حاضر checkoutSummary یک کامپوننت کاربردی است و من می توانم آن را به یک کامپوننت کلاس-محور تبدیل کنم و سپس این دو دکمه را در همین جا مدیریت کنم اما فکر می کنم زحمت این کار از زحمت پاس دادن prop ها بیشتر باشد بنابراین می گوییم:
<Button btnType="Danger" clicked={props.checkoutCancelled}> CANCEL </Button> <Button btnType="Success" clicked={props.checkoutContinued}> CONTINUE </Button>
من قرار است دو تابع را از طریق props به این دو دکمه پاس بدهم که البته هنوز آن ها را تعریف نکرده ایم. برای تعریف آن ها وارد کامپوننت Checkout.js شوید چرا که کامپوننت اصلی برای checkout همان Checkout.js می باشد. در قسمت JSX این فایل می گوییم:
return ( <div> <CheckoutSummary ingredients={this.state.ingredients} checkoutCancelled={} checkoutContinued={} /> </div> );
حالا که این دو prop را به CheckoutSummary پاس داده ایم باید خودشان را تعریف کنیم. خارج از تابع render و پایین تر از state می گویم:
checkoutCancelled = () => { } checkoutContinued = () => { }
ابتدا با تکمیل کردن کدهای checkoutCancelled شروع می کنیم:
checkoutCancelled = () => { this.props.history.goBack(); }
اگر یادتان باشد کامپوننت Checkout با استفاده از <Route> ها بارگذاری می شود بنابراین درون آن ها به prop های routing نیز دسترسی داریم. ما با استفاده از همین prop ها و متد goBack کاربر را به صفحه ی قبل می بریم. متد ()goBack یکی از متدهایی است که درون شیء history قرار دارد و کاربر را به صفحه ی قبل هدایت می کند. برای متد checkoutContinued هم می گوییم:
checkoutContinued = () => { this.props.history.replace('checkout/contact-data'); }
بنابراین اگر کاربر روی دکمه ی CONTINUE کلیک کند به مسیر checkout/contact-data می رود. توجه داشته باشید که ما هنوز این path را تعریف نکرده ایم و چیزی به نام contact-data نداریم اما در آینده آن را تعریف خواهیم کرد.
در نهایت به سادگی آن ها را به عنوان prop به کامپوننت CheckoutSummary پاس می دهیم:
return ( <div> <CheckoutSummary ingredients={this.state.ingredients} checkoutCancelled={this.checkoutCancelled} checkoutContinued={this.checkoutContinued} /> </div> );
حالا اگر به مرورگر برویم و خودمان را به صفحه ی checkout برسانیم دو گزینه برای انتخاب داریم:
با کلیک روی CANCEL به صفحه ی قبل که همان صفحه ی ساخت همبرگر است منتقل می شویم و با کلیک روی CANCEL آدرس مرورگر به http://localhost:3000/checkout/contact-data تبدیل می شود اما در ظاهر مرورگر هیچ تغییری را مشاهده نخواهیم کرد چرا که هنوز هیچ کدی برای مدیریت این مسیر خاص ننوشته ایم. این یعنی کد ما به درستی عمل می کند.
در حال حاضر برنامه ی ما یک مشکل دارد و آن این است که کامپوننت checkout از داده های واقعی استفاده نمی کند؛ اگر من یک همبرگر سفارش بدهم که اطلاعات زیر را داشته باشد:
پس از کلیک روی CONTINUE و انتقال به صفحه ی checkout هیچ شباهتی بین برگر نمایش داده شده و همبرگر من وجود ندارد. در واقع همبرگر نمایش داده شده در checkout یک همبرگر پیش فرض و ساده است و همبرگر واقعی که سفارش داده شده را نمایش نمی دهد. باید این مشکل را حل کنیم.
قبل از پرداختن به حل این مشکل باید با موضوعی به نام URLSearchParams آشنا شوید (گرچه که این مورد ربطی به React ندارد و جاوا اسکریپت عادی است که شما باید بلد باشید). من در این جلسه شما را با URLSearchParams آشنا می کنم.
یکی از مهم ترین کارها در توسعه ی front-end مدیریت query string یا query parameter ها است. اگر یک جست و جوی ساده در npm داشته باشید با انبوهی از پکیج ها مواجه می شوید که قرار است این مشکل را حل کنند اما اکثر کاربران نمی دانند که یک API جدید برای کار با query string ها وجود دارد که به نام URLSearchParams شناخته می شود. پشتیبانی مرورگرها از این API نیز بسیار عالی است و از ال 2016 به بعد پشتیبانی کامل پیاده سازی شده است.
URLSearchParams به عنوان پارامتر یک query string می گیرد (چه با علامت ؟
و چه بدون آن). اگر شما دوست دارید که تمام URL خود را به آن بدهید تا خودش پارامتر های query string را جدا کند باید از location.search استفاده کنید. فرض کنید ما یک URL کامل به شکل زیر داشته باشیم:
buy-shirts-here.com/filter?size=M&colour=red&sleeves=short
مقدار location.search برای این URL برابر با مقدار زیر خواهد بود:
?size=M&colour=red&sleeves=short
بنابراین می توانیم یک instance از URL خود بسازیم:
const url = new URL("https://buy-shirts-here.com/filter?filter?size=M&colour=red&sleeves=short")
سپس از دستور url.search استفاده کنیم که مقدار زیر را برمی گرداند:
?size=M&colour=red&sleeves=short
هر دو روش بدون مشکل هستند بنابراین راحت ترین روش به صورت زیر است:
const params = new URLSearchParams(location.search)
موارد و توابع کار با این API بسیار زیاد هستند که با مراجعه به صفحه ی توسعه دهندگان موزیلا با آن ها آشنا خواهید شد اما من مهم ترین موارد آن را ذکر می کنم. به طور مثال دستور has به شما می گوید که آیا پارامتر مورد نظر شما در URL موجود است یا خیر:
params.has('size') // => true params.has('button-style') // => false
برای خواندن مقدار یک پارامتر می توانید از get استفاده کنید. اگر پارامتر شما در کوئری موجود نباشد مقدار null به شما برگردانده خواهد شد:
params.get('size') // => 'M' params.get('button-style') // => null
البته باید حواستان به مورد خاصی نیز باشد. برخی از پارامتر های query string ها چندین مقدار دارند. به طور مثال به URL زیر نگاه کنید:
// URL: buy-shirts-here.com/filter?size=M&size=L
در این URL یک پارامتر به نام size داریم که دو بار تکرار شده است یا به عبارت دیگر دو مقدار دارد. اگر در چنین حالتی از get استفاده کنید فقط مورد اول را به شما برمیگرداند و اگر می خواهید تمام مقادیر را به دست بیاورید باید از getAll استفاده کنید تا تمام مقادیر به شکل یک آرایه به شما برگردانده شود:
// URL: buy-shirts-here.com/filter?size=M&size=L const params = new URLSearchParams(location.search) params.get('size') //=> 'M' params.getAll('size') //=> ['M', 'L']
همچنین اگر می خواهید بین پارامترها گردش کنید باید از ساختار خاص for of استفاده کنید. به مثال زیر توجه کنید:
// URL: buy-shirts-here.com/filter?size=M&size=L&colour=red const params = new URLSearchParams(location.search) for (let p of params) { console.log(p) } // => ['size', 'M'] // => ['size', 'L'] // => ['colour', 'red']
Let ای که تعریف کرده ایم (p) نماینده ی هر پارامتر خواهد بود. خروجی این console.log را به صورت کامنت در کد بالا برایتان قرار داده ام.
نکته ی مهم دیگر استفاده از سه دستور زیر است:
به مثال زیر دقت کنید:
// URL: buy-shirts-here.com/filter?size=M&size=L&colour=red const params = new URLSearchParams(location.search) console.log([...params.keys()]) // => ['size', 'size', 'colour'] console.log([...params.values()]) // => ['M', 'L', 'red'] console.log([...params.entries()]) // => [['size', 'M'], ['size', 'L'], ['colour', 'red']]
خروجی هر دستور را به صورت یک کامنت برایتان قرار داده ام تا متوجه نوع کار هر کدام بشوید.
متدهای بسیار زیادی برای کار با این API وجود دارد (مثل append و delete و toString و...) که تمامی آن ها در صفحه ی توسعه دهندگان موزیلا موجود است و می توانید به سادگی آن ها را مطالعه کنید. من این مقدمه را برایتان توضیح دادم تا در جلسه ی بعد به سراغ مدیریت query parameter ها برویم. در واقع برای داشتن یک همبرگر واقعی در checkout باید مقادیر سفارش داده شده را به صورت query string به کامپوننت checkout پاس داده و آن ها را دریافت کنیم.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.