เขียนเว็บด้วย Next.js + TypeScript ตอนที่ 2 - ว่าด้วยเรื่อง Routing และ Dynamic Routes
สวัสดีครับ มาต่อกันที่ ตอนที่ 2 วันนี้จะเป็นเรื่องของ Routing และ Dynamic Routes ครับ วันนี้จะเป็นเนื้อหาเพิ่มเติมของตอนที่ 1 เกี่ยวกับการสร้างหน้าเพจ และ Route
เขียนเว็บด้วย Next.js + TypeScript ตอนที่ 1
อย่างที่ยกตัวอย่างคร่าวๆ ในตอนที่ 1 ไปเรื่องของการสร้าง Pages ใน Next.js
- เมื่อเราเพิ่มไฟล์ในโฟลเดอร์ pages มันก็จะเป็น routes ให้อัตโนมัติ
- ก่อนหน้านี้เราสร้างหน้า About ก็คือเพิ่มไฟล์ pages/about.tsx จากนั้น routes ก็จะถูก generate เป็น /about ให้
Index Routes
เราสามารถกำหนดชื่อไฟล์เป็น index.tsx ก็ได้ หรือมีโฟลเดอร์หลายชั้นก็ได้ ตัว routes จะถูกแปลงเป็นแบบตัวอย่างนี้
pages/index.tsx
→/
pages/blog/index.tsx
→/blog
pages/about/index.tsx
→/about
Nested Routes
จะทำ routing หลายๆชั้นก็ทำได้ เช่น
pages/blog/first-post.tsx
→/blog/first-post
pages/dashboard/settings/username.tsx
→/dashboard/settings/username
Dynamic Routes
รองรับการทำ Dynamic Routes สมมติเราทำเว็บมีสินค้าในระบบ 1000 ชิ้น ต้องมาเขียนไฟล์ 1000 ไฟล์ ไม่ไหวแน่ๆ ตัว Next ก็รองรับ dynamic route แบบนี้
- ตั้งชื่อไฟล์หรือโฟลเดอร์ด้วย [] เช่น
[id].tsx
หรือ โฟลเดอร์[users]
pages/products/[id].tsx
→/products/:id
- เช่น /products/1 , /products/5pages/post/[...all].tsx
→/post/\*
(/post/2020/id/title)
ข้อดีคือ เราใช้แค่ไฟล์เดียว ที่ match กับ :id
ที่เราต้องการ
เรื่องของ Dynamic Routes
เราจะมาลงลึกในส่วน Dynamic Routes กันครับ เริ่มจาก เราจะกำหนดให้เว็บเรามี product เป็น url แบบนี้
/products/:id
เช่น /products/1 , /products/2
สิ่งที่เราต้องทำ ก็คือ สร้างไฟล์ [id].tsx
ขึ้นมา ในโฟลเดอร์ pages/products
เราสามารถ get params จาก [id]
ได้ด้วยการใช้ next/router
จากโค๊ดด้านบน ตัว Router จะ get object จาก params ที่เราตั้งชื่อไว้แบบเดียวกับชื่อไฟล์ นอกจากนี้ ตัว Router ยัง get query parameters ด้วยนะครับ ตัวอย่าง pages แบบต่างๆ จะได้ค่า query ยังไงบ้าง?
pages/products/[id]/[comment].tsx
->pages/products/1/my-comment
/pages/products/100?sku=test
ทีนี้เราลองทดสอบด้วยการ start dev server ขึ้นมา แล้วลองเข้าเว็บ ด้วย url ต่างๆ จะเห็นค่า product id ที่แตกต่างกัน
Catch all routes
ตัว Dynamic routes เรายังสามารถ ดักจับ path ทั้งหมด ได้ด้วยการใช้ 3จุด (…) ข้างใน [] ตัวอย่างเช่น
pages/posts/[...all].js
จะ match ทั้ง /posts/1, /posts/1/2/3, /posts/1/comments อะไรก็แล้วแต่ ที่ตามหลัง /posts จะเข้าเงื่อนไขทั้งหมด
การ Link กันระหว่างหน้า
ในตอนที่ 1 พูดไปแล้ว เรื่องการใช้ next/link
ตัวอย่างก่อนหน้านี้
เราอยากใส่ Link อะไรก็แค่เปลี่ยน href ใช่มั้ยครับ หรือถ้าจะส่ง query string ไปด้วย ก็เป็น href=“/products/1?color=red&size=m ก็ทำได้
หรือ เราจะส่งแบบ URL Object แบบนี้ก็ได้ ไม่ต้องนำ query มาต่อ url ให้วุ่นวาย
ลงมือโค๊ดดีกว่า
ลงมือทำดีกว่า เพื่อให้เห็นภาพจริงๆ เริ่มจาก ลองทำหน้าขึ้นมา หน้า 1 เป็นหน้า Product List ครับ ผมตั้งชื่อว่า pages/products/index.tsx มีข้อมูล mockProducts ใส่ไปด้วย เป็น ดังนี้
จากนั้นสร้างอีกไฟล์ สำหรับ Product Detail ชื่อ pages/products/[id].tsx
ตอนนี้เราจะมี 2 ไฟล์ ใน โฟลเดอร์ pages/products แล้วนะครับ คือ
index.tsx
- หน้า Products รวม จะเป็น route →/products
[id].tsx
- หน้า Detail จะเป็น route →/products/:id
ไฟล์ products/[id].tsx
จะมีข้อมูลดังนี้ แค่แสดงข้อมูล id จาก router
ทดลอง start dev server ดูผลลัพธ์
🎉 Done!
จบไปแล้วครับสำหรับตอนที่ 2 ไม่ได้เน้นหน้าตา UI นะครับ เน้นให้เข้าใจการทำงานของ Routes และ Dynamic Routes รวมถึงการอ่านค่าจาก router params เป็นต้น
- Authors
-
Chai Phonbopit
เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust