React Native ฉบับเริ่มต้น: สร้างแอปมือถือข้ามแพลตฟอร์ม (11/20)
การรับส่งข้อมูลระหว่างหน้าด้วย Navigation Params
สวัสดีครับเพื่อนๆ นักพัฒนา React Native ทุกท่าน! ในบทที่แล้ว เราได้เรียนรู้การใช้งาน React Navigation เพื่อสร้างระบบนำทางในแอปของเรากันไปแล้วนะครับ แต่การนำทางไปมาระหว่างหน้าอย่างเดียวอาจจะไม่เพียงพอ ในหลายๆ ครั้งเราจำเป็นต้องส่งข้อมูลจากหน้าหนึ่งไปยังอีกหน้าหนึ่งด้วย ซึ่งในบทนี้เราจะมาเรียนรู้วิธีการส่งและรับข้อมูลระหว่างหน้าต่างๆ ผ่านสิ่งที่เรียกว่า "Navigation Params" หรือ พารามิเตอร์ของการนำทาง กันครับ
Navigation Params เปรียบเสมือนกระเป๋าเดินทางที่เราสามารถใส่ข้อมูลต่างๆ ลงไป แล้วส่งไปพร้อมกับการเดินทางไปยังหน้าใหม่ เมื่อไปถึงหน้าปลายทาง เราก็สามารถเปิดกระเป๋าใบนั้นแล้วหยิบข้อมูลที่ต้องการออกมาใช้งานได้
การส่ง Params เมื่อ Navigate
การส่ง Params ทำได้ง่ายมากครับ เพียงแค่เพิ่ม object ที่มี key-value pairs เป็น argument ที่สองของฟังก์ชัน navigation.navigate() ครับ มาดูตัวอย่างกันเลย:
import React from 'react';
import { View, Button, Text } from 'react-native';
const HomeScreen = ({ navigation }) => {
const handleGoToDetail = () => {
navigation.navigate('Detail', {
itemId: 86,
otherParam: 'ข้อมูลเพิ่มเติม'
});
};
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>หน้าหลัก</Text>
<Button
title="ไปยังหน้ารายละเอียด"
onPress={handleGoToDetail}
/>
</View>
);
};
export default HomeScreen;
จากโค้ดด้านบน ในฟังก์ชัน handleGoToDetail เราได้เรียก navigation.navigate('Detail', ...) โดย argument ที่สองคือ object { itemId: 86, otherParam: 'ข้อมูลเพิ่มเติม' } นี่แหละครับคือ Navigation Params ที่เรากำลังส่งไป
ในตัวอย่างนี้ เราส่งข้อมูลสองอย่างคือ itemId ซึ่งเป็นตัวเลข และ otherParam ซึ่งเป็นข้อความ เราสามารถส่งข้อมูลประเภทอื่นๆ ได้เช่นกัน เช่น boolean, array หรือ object อื่นๆ
การรับ Params ในหน้าปลายทาง
เมื่อเราส่ง Params ไปแล้ว ในหน้าปลายทาง (ในตัวอย่างนี้คือหน้า Detail) เราจะรับ Params เหล่านั้นได้อย่างไร? คำตอบคือเราสามารถเข้าถึง Params ได้ผ่าน props ของ Component ครับ โดยเฉพาะ prop ที่ชื่อว่า route ซึ่งเป็น object ที่มี property ชื่อ params อยู่
import React from 'react';
import { View, Text } from 'react-native';
const DetailScreen = ({ route, navigation }) => {
// ดึงค่า Params ออกมา
const { itemId, otherParam } = route.params;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>หน้ารายละเอียด</Text>
<Text>Item ID: {JSON.stringify(itemId)}</Text>
<Text>Other Param: {JSON.stringify(otherParam)}</Text>
</View>
);
};
export default DetailScreen;
จากโค้ดด้านบน เราได้ทำการ destructuring route.params เพื่อดึงค่า itemId และ otherParam ออกมา แล้วนำไปแสดงผลบนหน้าจอ
JSON.stringify() ถูกใช้เพื่อแปลงค่า itemId และ otherParam เป็น string เพื่อให้สามารถแสดงผลใน Text Component ได้อย่างถูกต้อง
การใช้งาน Params อย่างปลอดภัย
สิ่งสำคัญอย่างหนึ่งในการใช้งาน Navigation Params คือการตรวจสอบว่า Params ที่เราต้องการนั้นมีอยู่จริงหรือไม่ เพราะถ้าไม่มีอยู่จริง แล้วเราพยายามเข้าถึงค่าของมัน จะทำให้แอปพลิเคชันของเราเกิด error ได้
วิธีที่ง่ายที่สุดในการตรวจสอบว่า Params มีอยู่จริงหรือไม่ คือการใช้ optional chaining (?.) หรือ default value:
import React from 'react';
import { View, Text } from 'react-native';
const DetailScreen = ({ route, navigation }) => {
// ใช้ optional chaining เพื่อป้องกัน error
const itemId = route.params?.itemId;
const otherParam = route.params?.otherParam;
// หรือใช้ default value
const defaultItemId = route.params?.itemId ?? 'ไม่มีข้อมูล';
const defaultOtherParam = route.params?.otherParam ?? 'ไม่มีข้อมูล';
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>หน้ารายละเอียด</Text>
<Text>Item ID: {JSON.stringify(itemId)}</Text>
<Text>Other Param: {JSON.stringify(otherParam)}</Text>
<Text>Default Item ID: {JSON.stringify(defaultItemId)}</Text>
<Text>Default Other Param: {JSON.stringify(defaultOtherParam)}</Text>
</View>
);
};
export default DetailScreen;
Optional Chaining (?.): ถ้า route.params หรือ route.params.itemId เป็น null หรือ undefined มันจะ return undefined โดยไม่ throw error
Nullish Coalescing Operator (??): ถ้า route.params?.itemId เป็น null หรือ undefined มันจะ return ค่าทางขวาของ operator (ในที่นี้คือ 'ไม่มีข้อมูล')
การใช้เทคนิคเหล่านี้จะช่วยให้แอปพลิเคชันของเรามีความเสถียรมากขึ้น และป้องกัน error ที่อาจเกิดขึ้นจากการที่ Params ไม่ได้ถูกส่งมา
กรณีใช้งานจริงและข้อผิดพลาดที่พบบ่อย
กรณีใช้งานจริง:
- ส่ง ID ของสินค้า: เมื่อผู้ใช้คลิกที่สินค้าในหน้ารายการสินค้า เราสามารถส่ง ID ของสินค้านั้นไปยังหน้า Detail เพื่อแสดงรายละเอียดของสินค้านั้นๆ
- ส่งข้อมูลผู้ใช้: หลังจากที่ผู้ใช้ Login สำเร็จ เราสามารถส่งข้อมูลผู้ใช้ (เช่น ชื่อ, อีเมล, รูปโปรไฟล์) ไปยังหน้า Profile เพื่อแสดงข้อมูลส่วนตัวของผู้ใช้
- ส่งสถานะการทำงาน: เมื่อมีการทำรายการบางอย่าง (เช่น การสั่งซื้อ) เราสามารถส่งสถานะของรายการนั้น (เช่น รอการชำระเงิน, กำลังจัดส่ง, สำเร็จ) ไปยังหน้า Status เพื่อแสดงสถานะล่าสุดของรายการนั้น
ข้อผิดพลาดที่พบบ่อย:
- ลืมส่ง Params: บ่อยครั้งที่เราอาจจะลืมส่ง Params ไปพร้อมกับการ Navigate ทำให้หน้าปลายทางไม่สามารถดึงข้อมูลที่ต้องการได้
- ชื่อ Params ไม่ถูกต้อง: การสะกดชื่อ Params ผิด (เช่น
itemIdกลายเป็นitemID) จะทำให้หน้าปลายทางไม่สามารถหา Params ที่ต้องการได้ - ไม่ได้ตรวจสอบ Params: การไม่ตรวจสอบว่า Params มีอยู่จริงหรือไม่ อาจทำให้แอปพลิเคชันเกิด error เมื่อ Params ไม่ได้ถูกส่งมา
Performance, Security, Trade-offs เชิงสถาปัตยกรรม
Performance: การส่ง Params จำนวนมากอาจส่งผลต่อ performance ของแอปพลิเคชันได้เล็กน้อย โดยเฉพาะอย่างยิ่งถ้า Params นั้นมีขนาดใหญ่ (เช่น รูปภาพ, วิดีโอ) ทางที่ดีควรส่งเฉพาะข้อมูลที่จำเป็นจริงๆ เท่านั้น และถ้าข้อมูลมีขนาดใหญ่มาก ควรพิจารณาใช้วิธีการอื่นในการส่งข้อมูล เช่น การใช้ State Management Library (Redux, Context API) หรือการบันทึกข้อมูลลงใน AsyncStorage
Security: Navigation Params ไม่ควรใช้สำหรับส่งข้อมูล sensitive (เช่น รหัสผ่าน, ข้อมูลบัตรเครดิต) เพราะ Params เหล่านี้สามารถถูกดักจับได้ง่าย ทางที่ดีควรเข้ารหัสข้อมูล sensitive ก่อนที่จะส่ง หรือใช้วิธีการอื่นในการส่งข้อมูล เช่น การใช้ HTTPS เพื่อเข้ารหัสการสื่อสารระหว่างแอปพลิเคชันและ Server
Trade-offs เชิงสถาปัตยกรรม: การใช้ Navigation Params มากเกินไป อาจทำให้ Component ของเรามีความซับซ้อนและยากต่อการบำรุงรักษา ทางที่ดีควรพิจารณาใช้ State Management Library (Redux, Context API) เพื่อจัดการ State ส่วนกลางของแอปพลิเคชัน และลดการพึ่งพา Navigation Params
สรุป
ในบทนี้ เราได้เรียนรู้วิธีการส่งและรับข้อมูลระหว่างหน้าต่างๆ ผ่าน Navigation Params ซึ่งเป็นเครื่องมือที่มีประโยชน์มากในการสร้างแอปพลิเคชัน React Native ที่มีการนำทางที่ซับซ้อน อย่าลืมนำความรู้ที่ได้เรียนรู้ไปประยุกต์ใช้ในการพัฒนาแอปพลิเคชันของคุณนะครับ
ในบทต่อไป เราจะมาเรียนรู้เกี่ยวกับการบันทึกข้อมูลแบบ Local ด้วย AsyncStorage กันครับ เตรียมตัวให้พร้อม แล้วพบกันใหม่ในบทหน้า!