React-navigation คือไลบรารี Navigation ที่คิดถึงเมื่อพูดถึง Navigation ใน React Native
ผมเป็นแฟนใหญ่ของไลบรารีนี้ และมันเป็น Solution แรกที่ผมใช้จัดการ Navigation ใน React Native ส่วนหนึ่งเพราะมี API ยอดเยี่ยมและง่าย และ Customizable มาก
ผมเขียนบทความนี้เพราะ Version 5 เพิ่งเปลี่ยนจาก Beta เป็น Stable มาพร้อม Feature Changes และ API Design ใหม่ที่ให้วิธีประกาศ Routes 简单และต่างออกไป
ในบทความนี้ เราจะผ่าน New APIs และดูวิธีใช้ในแอปพลิเคชันของเรา
Originally published on saidhayani.com
การติดตั้ง
วิธีติดตั้ง react-navigation เปลี่ยนไปนิดหน่อยเทียบกับเวอร์ชันก่อนหน้า (>4.x):
// > 4.x versions
yarn add react-navigation
การติดตั้ง react-navigation 5 จะเป็นแบบนี้:
// yarn
yarn add @react-navigation/native
// npm
npm install @react-navigation/native
เวอร์ชันล่าสุดของ react-navigation ใช้ Third Party Libraries มาก เช่น react-native-gesture-handler สำหรับ Animation และ Transitions ดังนั้นคุณต้องติดตั้ง Libraries นั้นเสมอ
// yarn
yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
// npm
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
Dynamic Screens
API ใหม่ Introduce Dynamism ในการ Initialize Routes ก่อนหน้านี้ทำแบบ Static — 基本上 เราต้อง Define Routes ใน Config File
// @flow
import React from "react";
import { createAppContainer, createSwitchNavigator } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
/** ---------Screens----------- */
// import LaunchScreen from "../Containers/LaunchScreen";
import HomeScreen from "../Containers/HomeScreen";
import ProfileScreen from "../Containers/ProfileScreen";
import LoginScreen from "../Containers/LoginScreen";
const StackNavigator = createStackNavigator(
{
initialRouteName: "Home"
},
{
Home: { screen: HomeScreen },
Login: { screen: LoginScreen, headerMode: "none", },
Profile: { screen: ProfileScreen }
});
export default createAppContainer(StackNavigator);
API ใหม่มาพร้อม Dynamic Components และทำให้ Navigation เป็น Dynamic มากขึ้น
วิธีใหม่ในการประกาศ Routes จะคล้ายกับนี้:
import React from "react"
import { SafeAreaView, StyleSheet, View, Text, StatusBar } from "react-native"
import { NavigationContainer } from "@react-navigation/native"
import { createStackNavigator } from "@react-navigation/stack"
const App: () => React$Node = () => {
return (
<>
>
)
}
const Stack = createStackNavigator()
const AppNavigation = () => {
return (
)
}
const HomeScreen = () => {
return (
Home Screen
)
}

วิธีใหม่นี้ Dynamic, ใช้ง่ายขึ้น และค่อนข้างคล้าย React Router API
Dynamic Options
นี่เป็น Feature ที่ Community ขอมานานที่สุด ผมเคยมีปัญหากับ Old Method (Static) และยากมากที่จะเปลี่ยน Navigation Behavior แบบ Dynamic
The Old Method => < 4.x
กับ Older Versions ของ react-navigation เราต้อง Define Static Options และไม่มีทางเปลี่ยนแบบ Dynamic
static navigationOptions = {
title: "Sign In",
header: null,
mode: "modal",
headerMode: "none"
};
The New Method (Version 5)
React-navigation มาพร้อม Dynamic Method ที่ง่ายมาก เราสามารถ Set Options ให้ Screen ใดๆ ได้แค่ใช้ props
const AppNavigation = ({}) => {
let auth = {
authenticated: true,
user: {
email: "user@mail.com",
username: "John",
},
}
let ProfileScreenTitle = auth.authenticated ? auth.user.username : "Profile"
return (
)
}

ด้วย Dynamic Options ผมสามารถเปลี่ยน Title ตาม Authentication ได้ เช่น ถ้า User Authenticated ผมตั้ง Screen Title เป็น Username หรือเปลี่ยน Background Color ของ Header
นี่มีประโยชน์มากโดยเฉพาะถ้าคุณใช้ Dynamic Themes หรืออยาก Implement Dark Mode ในแอป
Hooks
นี่คือ Feature โปรดของผมจนตอนนี้ และเป็น Time-saver API ใหม่ Introduce Custom Hooks บางอย่างเพื่อทำ Actions บางอย่าง
ใน Previous Versions ตัวอย่างเช่น ถ้าผมต้องได้ Current Name ของ Active Screen ผมต้องสร้าง Helpers ทำให้ผมค่อนข้างมาก ประมาณนี้:
export function getCurrentRouteName(): string | null {
const tag = "[getCurrentRouteNameSync] "
const navState = getStore().getState().nav
const currentRoute = getActiveRouteState(navState)
console.log(tag + " currentRoute > ", currentRoute)
return currentRoute && currentRoute.routeName ? currentRoute.routeName : null
}
Hooks API ช่วยให้ผมหลีกเลี่ยงทั้งหมดนี้ และทำให้เข้าถึง Navigation API ได้ง่ายด้วย Single Line ใช้ Hook
ตอนนี้ผมได้ RouteName ง่ายด้วย Hook useRoute
import { useRoute } from "@react-navigation/native"
const AboutScreen = ({ navigation }) => {
const route = useRoute()
return (
{/* Display the RouteName here */}
{route.name}
)
}
เราทำได้เหมือนกันกับ Hook useNavigationState มันให้เราเข้าถึง Navigation State
const navigationState = useNavigationState(state => state)
let index = navigationState.index
let routes = navigationState.routes.length
console.log(index)
console.log(routes)
React-navigation ยังมี Hooks อื่นๆ เช่น:
useFocuseEffect: Side Effect Hook ที่เมื่อ Screen โหลด คืนค่า Focused ScreenuseLinking: จัดการ Deep Linking
ผมแนะนำให้ Check ออกมากัน
Wrapping Up
React-navigation API ใหม่ Definitely Moves จาก Static ไป Dynamic นี่เป็นทิศทางที่ยอดเยี่ย่ จะเปลี่ยนวิธีเราจัดการ Navigation ใน React Native อย่างแน่นอน Dynamic Routes เป็น Major Request ของ React-navigation Users และวิธีใหม่นี้จะช่วยให้เราสร้าง User Navigation Experience ที่ดีขึ้น
You can find more content about React Native here
Thanks for reading
- GitHub
- Join the mail-list
Looking for a React Native developer for your project? Hit me up.