# صفحه پست و کامنتها
با شکلگیری مفهوم Single Page Application ها، نیاز به امکانی برای جابجا کردن کاربر بین صفحات مختلف احساس شد. به این شکل که با کلیک کردن کاربر روی یک لینک، نیاز بود که url صفحه عوض شه و برای این که کاربر حس نکنه که صفحه داره کامل عوض میشه، یک سری المانهای صفحه مثل header باقی میمونند. همچنین به توسعهدهنده ها این امکان رو میداد که با رد و بدل کردن اطلاعات کمی، یک صفحه جداگونه رو نسبت به صفحه قبل، به کاربر نشون بدن.Routing به فرایندی گفتهمیشه که طی اون، کاربر لینکی رو از application میخواد و application تصمیم میگیره که کدوم صفحه باید به کاربر نشون داده بشه.
# Coding style
برای مرتبسازی کد از ابزارهایی استفاده میشه. این ابزارها بر اساس قوانینی کد رو مرتب میکنند و در صورت رعایت نکردنشون خطا یا هشدار نشون میدن. رعایت این قوانین باعث خوانایی بهتر کد و consistency پروژه میشه.
eslint رو نصب کن و از تنظیمات recommended و airbnb استفاده کن.
همچنین برای همه کامپوننتهای ریاکت که مینویسی حتما propType هم بنویس تا معلوم باشه هر کامپوننت نیاز به چه فیلدهایی داره.
# ریاکت Router
با توجه به اینکه نشون دادن کانتن با توجه به url و تصمیمگیری اون در سمت کلاینت میتونه به مرور و برای لینکهای داینامیک پیچیده بشه، از پکیج آمادهی react-router استفاده میکنیم که انواع مرورگرها رو میتونه ساپورت کنه.لینکهای زیر رو از مستندات react-router بخون:
و همه مثالهایی که تو همون سایت آورده شده رو یه نگاه بنداز تا کامل یاد بگیری چجوری کار میکنه.
در ادامه میخوایم این پکیج رو به پروژه اضافه کنیم. خود create-react-app توضیحات خوبی برای اضافه کردن router بهمون میده: لینک
# صفحه پست
تا الان روی صفحه خانه کار میکردیم که لیست پستها رو نشون میده (با آدرس /). حالا میریم سراغ صفحه /post/:id که یه پست رو نشون میده.
با این اوصاف، علاوه بر کامپوننت App که از قبل وجود داشت، به سه کامپوننت دیگه نیاز داریم:
Home: برای نشون دادن لیست پستها
PostPage: برای نشون دادن صفحه پست (کامپوننتی که به react-router میدیم)
Post: که کامپوننت اصلی یک پست هست و رندرش میکنه و دو کامپوننت دیگه ازش استفاده میکنن.
از کامپوننت App فقط برای نمایش Header و Routing استفاده میکنیم.
فایل PostService تا الان فقط یک endpoint داشت و اون هم برای گرفتن لیست پستها بود. Endpoint جدیدی باید بهش اضافه بشه که فقط اطلاعات مربوط به یک پست رو میگیره. آدرسش اینه:
localhost:3000/posts/[id]
حالا title پستهایی که داشتیم رو به لینکِ روتر تبدیل کن. با کلیک کردن روشون صفحه مربوط به همون پست باید نشون داده بشه. برای نمایش یک پست تکی نمیخوایم کامپوننت Post زیاد پیچیده بشه و منطق فراخوانی api مستقیما داخلش نوشته بشه، برای ارائه یه راه حل بهتر این لینک رو حتما بخون.
# کامنتها
تو صفحه پست، علاوه بر خود متن، میخوایم کامنتهای مربوط به اون پست رو هم نشون بدیم. Endpoint مربوط به کامنتهای یک پست، اینه:
localhost:3000/posts/[id]/comments
در این قسمت قرار نیست که ارسال کامنت رو اضافه کنیم، و فقط نمایششون کفایت میکنه.
اول یه کامپوننت به اسم CommentSection پیاده سازی کن که با گرفتن یه آرایه از کامنتها، اونا رو با styling مناسب توی صفحه نشون بده. از این کامپوننت داخل PostPage استفاده کن و تابع گرفتن لیست کامنتها رو (که قبلا توی PostService پیادهسازی کردی)، تو این کامپوننت صدا بزن.
در ادامه با توجه به این لینک که گفتیم بخونی کامپوننت CommentSection رو به دو کامپوننت مجزا تقسیم کن که یکی صرفا وظیفه نمایش کامنت رو داره و اون یکی فراخوانی به api رو انجام میده. همچنین بررسی کن آیا میشه به کامپوننتهای کوچیکتری هم تقسیم بشه تا پیچیدگی کمتر بشه یا نه؟
برای این دو قسمتِ پست و کامنتها loading مناسب تعریف کن. یعنی تا وقتی محتوای هر کدوم لود نشده، داخل اون قسمت بنویس: «در حال بارگذاری...».
# ساختار درختی کامنتها
بعضی از کامنتهایی که از سرور میگیری، فیلد parent_idشون، null هست. اون ها کامنتهایی هستند که مربوط به خود پست هستند. سایر کامنتها که مقدار این فیلد براشون یک عدد ست شده، در پاسخ (reply) به کامنتی با آیدی parent_id ارسال شدن. در نتیجه باید زیر parentش نشون دادهبشه. همچنین تمام کامنتها باید دکمهای داشتهباشند برای پاسخ دادن به اون کامنت؛ که با کلیک روی اون، میشه جوابی به خود اون کامنت فرستاد. که البته باز هم نیازی به ارسال پاسخ به سرور وجود نداره و فقط وجود این فیلد ورودی کفایت میکنه.
# ارسال comment
حالا میخوایم امکان ارسال comment رو اضافه کنیم. برای ارسال comment جدید به endpoint کامنتهای یک پست با متد POST ریکوئست میزنیم و فیلدهای مرتبط رو برای سرور میفرستیم. نکته مهم در این قسمت، اینه که فیلد parent_id هم باید متناسب با جایی که کامنت داره ارسال میشه، به سرور بره.
ارسال کامنت برای یک پست بدونِ ثبتنام و لاگین باید برای همه قابل انجام باشه. به همین دلیل به فیلدهایی برای دریافتِ «نام» و «متنِ کامنت» نیاز داریم.
سایر فیچرهای این قسمت، به شکل زیر هست:
در صورتی که ارتفاع متن نوشتهشده توسط کاربر، از ارتفاع تعبیه شده برای این فیلدِ متنِ کامنت بیشتر باشه، نباید به اون فیلد اسکرول اضافه بشه، بلکه باید طول فیلد هم افزایش پیدا کنه.
در صورتی که کاربر ctrl + enter رو میزنه، کامنت ارسال میشه به سرور (دکمه Send Comment هم داشته باشه که همین کار رو میکنه)
اطلاعاتی که به سرور میفرستی، شامل موارد زیر هست:
- هدر تعیین کننده نوع اطلاعات فرستاده شده به سرور (json)
- اطلاعات کامنت (به صورت json) شامل:
- author (string)
- body (string)
- date (string)
- parent_id (null | number)
این کامنت رو بدون گرفتن لیست دوباره کامنتها به صفحه اضافه کن.