Dynamic Routing คืออะไรและทำไมเราต้องใช้มัน
เวลาเราสร้างเว็บ เรามักจะเจอสถานการณ์ที่หน้าตาเว็บเหมือนกัน แต่ข้อมูลต่างกัน เช่น หน้าโปรไฟล์ผู้ใช้งาน หรือหน้าอ่านบทความ ถ้าเราต้องสร้างไฟล์แยกกันทุกหน้าคงไม่ไหว Dynamic Routing (เส้นทางที่เปลี่ยนไปตามข้อมูล) จึงเข้ามาช่วยจัดการเรื่องนี้
ลองนึกภาพว่าคุณเป็นบรรณารักษ์ที่มีหนังสือเป็นล้านเล่ม คุณคงไม่ทำป้ายชื่อหนังสือแปะไว้หน้าห้องทุกเล่ม แต่คุณจะใช้ระบบเลขรหัสแทน เช่น /book/1 หรือ /book/2 เพื่อบอกว่าให้ไปหยิบเล่มไหนมาอ่าน วิธีนี้ช่วยให้เราเขียนโค้ดแค่หน้าเดียวแต่ดึงข้อมูลมาแสดงได้ไม่จำกัดครับ
ในการเขียนโปรแกรม เราเรียกตัวเลขหรือรหัสที่เปลี่ยนไปนี้ว่า Params (พารามิเตอร์ หรือตัวแปรที่รับค่ามาจาก URL) การใช้มันใน React ร่วมกับ TypeScript (ภาษาที่เพิ่มระบบตรวจสอบประเภทข้อมูลให้ JavaScript) จะช่วยให้เรามั่นใจว่าข้อมูลที่เราดึงมานั้น "ถูกประเภท" และไม่ทำให้เว็บพังกลางคันครับ
การติดตั้งและตั้งค่า Route แบบมีตัวแปร
ก่อนอื่นเราต้องใช้ไลบรารีที่ชื่อว่า react-router-dom เพื่อจัดการเรื่องการเปลี่ยนหน้าเว็บ ขั้นตอนแรกคือการกำหนด Route (เส้นทางในเว็บ) ให้รองรับค่าพารามิเตอร์โดยใช้เครื่องหมาย : นำหน้าชื่อตัวแปรที่เราต้องการ
ถ้าเราต้องการสร้างหน้าแสดงข้อมูลผู้ใช้ เราต้องบอกโปรแกรมว่าให้รอรับค่า id เข้ามานะ วิธีนี้เหมือนการเตรียมช่องว่างไว้ในแบบฟอร์ม เพื่อรอให้คนกรอกข้อมูลเข้ามาเติมเต็มในภายหลังครับ
- ติดตั้งไลบรารีด้วยคำสั่ง
npm install react-router-domในเทอร์มินัล - กำหนดเส้นทางในไฟล์หลักโดยใช้
path="/user/:userId" - เมื่อผู้ใช้เข้าเว็บผ่านลิงก์
/user/123ตัวแปรuserIdจะมีค่าเป็น"123"ทันที
// การตั้งค่า Route ในไฟล์หลัก
<Routes>
<Route path="/user/:userId" element={<UserProfile />} />
</Routes>
ในโค้ดตัวอย่าง เราบอก React ว่าถ้ามีคนเข้าลิงก์ที่หน้าตาเป็น /user/ ตามด้วยอะไรก็ได้ ให้ส่งคนนั้นไปที่คอมโพเนนต์ UserProfile ทันที และเราจะเอาค่า userId ไปใช้ต่อได้ในหน้านั้นครับ
การดึง Params ด้วย useParams และการกำหนด Type
พอเราเข้าหน้า UserProfile แล้ว เราจะดึงค่า userId ออกมาได้อย่างไร? เราจะใช้ฟังก์ชันที่ชื่อว่า useParams (เครื่องมือดึงค่าพารามิเตอร์จาก URL) ซึ่งใน TypeScript เราต้องระบุประเภทข้อมูลให้มันด้วย เพื่อให้โปรแกรมรู้ว่า userId คือข้อความหรือตัวเลข
ลองจินตนาการว่าคุณได้รับกล่องพัสดุมา 1 ใบ แต่คุณไม่รู้ว่าข้างในเป็นอะไร TypeScript ก็คือการแปะป้ายบอกว่า "กล่องนี้คือของเล่นนะ" ทำให้เราไม่ต้องเดาว่าข้างในคืออะไร และลดโอกาสเกิดบั๊ก (ข้อผิดพลาดของโปรแกรม) ที่เกิดจากการเรียกใช้ข้อมูลผิดประเภทครับ
// การดึง params ด้วย useParams<ParamsType>()
type ParamsType = {
userId: string; // กำหนดว่า userId ต้องเป็นข้อความเสมอ
};
const UserProfile = () => {
const { userId } = useParams<ParamsType>();
return <div>กำลังแสดงข้อมูลผู้ใช้ ID: {userId}</div>;
};
ข้อควรระวังคือ Params ที่ได้จาก URL จะเป็น string (ข้อความ) เสมอ แม้คุณจะใส่เป็นตัวเลขใน URL ก็ตาม ถ้าคุณต้องการเอาไปคำนวณ คุณต้องแปลงมันเป็นตัวเลขก่อนด้วยฟังก์ชัน Number() ครับ
การจัดการ Query String สำหรับข้อมูลเสริม
บางครั้งเราไม่ได้ต้องการแค่ id แต่ต้องการข้อมูลเสริม เช่น การค้นหาหรือการคัดกรองข้อมูล เราจะใช้สิ่งที่เรียกว่า Query String (ข้อความที่ต่อท้าย URL หลังเครื่องหมาย ?) เช่น /products?category=shoes เพื่อบอกเว็บว่าเราต้องการดูรองเท้า
วิธีนี้เหมือนการไปร้านอาหารแล้วคุณสั่งเมนูเดิม แต่ระบุเงื่อนไขเพิ่มว่า "เอาแบบไม่ใส่ผัก" ข้อมูลหลักคือเมนู ส่วนเงื่อนไขคือ Query String นั่นเองครับ เราสามารถดึงค่าเหล่านี้มาใช้ใน React ได้โดยใช้ useSearchParams
// การดึงค่าจาก Query String
const [searchParams] = useSearchParams();
const category = searchParams.get("category"); // ดึงค่าจาก ?category=...
// ผลลัพธ์: ถ้า URL เป็น /products?category=shoes ค่า category จะเท่ากับ "shoes"
จุดที่มือใหม่มักพลาดคือการลืมจัดการกรณีที่ไม่มี Query String ส่งมา ทำให้โปรแกรมพยายามเรียกใช้ค่าว่างเปล่าจนค้าง แนะนำให้เขียนเงื่อนไขตรวจสอบเสมอว่าค่าที่ได้มามีจริงหรือไม่ก่อนนำไปแสดงผลครับ
การทำ Programmatic Navigation แบบมี Type
ปกติเราเปลี่ยนหน้าด้วยลิงก์ แต่บางครั้งเราอยากให้โปรแกรมเปลี่ยนหน้าเองหลังจากทำงานบางอย่างเสร็จ เช่น หลังจากกดปุ่ม "บันทึก" แล้วให้เด้งไปหน้าโปรไฟล์ เราเรียกสิ่งนี้ว่า Programmatic Navigation (การสั่งให้เว็บเปลี่ยนหน้าด้วยโค้ด)
เราจะใช้ฟังก์ชัน useNavigate (เครื่องมือสั่งย้ายหน้าเว็บ) ในการจัดการเรื่องนี้ครับ การทำแบบนี้ช่วยให้ประสบการณ์การใช้งานของผู้ใช้ดูลื่นไหลและเป็นมืออาชีพมากขึ้น เพราะเราสามารถควบคุมจังหวะการเปลี่ยนหน้าได้แม่นยำครับ
// การสั่งเปลี่ยนหน้าด้วยโค้ด
const navigate = useNavigate();
const handleSave = () => {
// ทำการบันทึกข้อมูล...
navigate("/dashboard"); // สั่งให้ย้ายไปหน้า dashboard
};
ถ้าคุณต้องการส่งข้อมูลไปกับหน้าใหม่ด้วย คุณสามารถใช้ state ใน navigate ได้ แต่ต้องระวังอย่าส่งข้อมูลขนาดใหญ่เกินไป เพราะจะทำให้เว็บช้าลง การส่งแค่ id แล้วไปโหลดข้อมูลใหม่ในหน้าถัดไปเป็นวิธีที่ปลอดภัยกว่าครับ
สรุป: เอาไปปรับใช้ในโปรเจกต์จริง
ทั้งหมดนี้คือหัวใจของการจัดการเส้นทางในเว็บสมัยใหม่ การเข้าใจ Dynamic Routing ช่วยให้คุณสร้างแอปพลิเคชันที่ยืดหยุ่นและรองรับข้อมูลจำนวนมากได้ หากคุณกำลังฝึกทำโปรเจกต์ Portfolio (ผลงานส่วนตัว) ผมแนะนำให้ลองสร้างหน้าเว็บที่แสดงรายชื่อโปรเจกต์แล้วกดเข้าไปดูรายละเอียดโดยใช้ params ดูครับ
ตัวอย่างการใช้งานจริง: สมมติคุณทำเว็บ "สมุดโทรศัพท์" เมื่อคุณกดที่ชื่อเพื่อนคนหนึ่ง เว็บจะนำคุณไปที่ /contact/:id โดยใช้ useParams เพื่อดึงข้อมูลเพื่อนคนนั้นมาแสดง ถ้าคุณต้องการค้นหาเพื่อนในรายชื่อ ก็ใช้ Query String เช่น /contacts?search=somchai เพื่อกรองข้อมูลให้เหลือแค่ชื่อที่คุณต้องการ
จำไว้ว่าการเรียนรู้เรื่องพวกนี้ไม่ได้อยู่ที่การจำคำสั่งได้ทั้งหมด แต่อยู่ที่การเข้าใจว่า "ข้อมูลไหลไปที่ไหนและอย่างไร" ฝึกเขียนโค้ดบ่อย ๆ แล้วคุณจะพบว่าการจัดการเส้นทางเหล่านี้จะกลายเป็นเรื่องง่ายเหมือนการปอกกล้วยเข้าปากครับ ขอให้สนุกกับการเขียนโค้ดครับ!