💫
React Native (Expo)での画面遷移いろいろまとめ
はじめに
最近 Expo に入門しました!
この記事では Expo Router や React Navigation での画面遷移のいくつかを Gif 画像と共に紹介します!
外部リンク
以下から一覧でも確認できるようにしています!(Tamagui を試したかっただけ 😅)
この記事で紹介するサンプルコードのリポジトリです!
Stack
import { Stack } from "expo-router";
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="(tabs)" />
<Stack.Screen
name="stack"
options={{ headerBackButtonDisplayMode: "minimal" }}
/>
</Stack>
);
}
Tab
import { Tabs } from "expo-router";
export default function TabLayout() {
return (
<Tabs>
<Tabs.Screen name="index" />
<Tabs.Screen name="explore" />
</Tabs>
);
}
Modal
import { Stack } from "expo-router";
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="(tabs)" />
<Stack.Screen name="modal" options={{ presentation: "modal" }} />
</Stack>
);
}
Drawer
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { Drawer } from "expo-router/drawer";
export default function DrawerLayout() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<Drawer>
<Drawer.Screen name="drawer1" />
<Drawer.Screen name="drawer2" />
</Drawer>
</GestureHandlerRootView>
);
}
メニューのカスタマイズする場合
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { Drawer } from "expo-router/drawer";
import {
DrawerContentComponentProps,
DrawerContentScrollView,
DrawerItem,
DrawerItemList,
} from "@react-navigation/drawer";
import { router } from "expo-router";
import Feather from "@expo/vector-icons/Feather";
import { Text } from "react-native";
function CustomDrawerContent(props: DrawerContentComponentProps) {
return (
<DrawerContentScrollView>
<Text style={{ textAlign: "center", padding: 16 }}>Hello Drawer</Text>
<DrawerItemList {...props} />
<DrawerItem
label="Stack"
onPress={() => router.push({ pathname: "/stack" })}
icon={(props) => <Feather name="smile" size={24} color={props.color} />}
/>
</DrawerContentScrollView>
);
}
export default function CustomDrawerLayout() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<Drawer drawerContent={CustomDrawerContent}>
<Drawer.Screen
name="custom-drawer1"
options={{
title: "Drawer 1",
drawerIcon: (props) => (
<Feather name="frown" size={24} color={props.color} />
),
}}
/>
<Drawer.Screen
name="custom-drawer2"
options={{
drawerIcon: (props) => (
<Feather name="meh" size={24} color={props.color} />
),
}}
/>
</Drawer>
</GestureHandlerRootView>
);
}
検索
import { router, Stack } from "expo-router";
export default function SearchLayout() {
return (
<Stack
screenOptions={{
headerSearchBarOptions: {
placeholder: "検索する",
inputType: "text",
onSearchButtonPress(e) {
router.push({
pathname: "/search-result",
params: { q: e.nativeEvent.text },
});
},
},
}}
>
<Stack.Screen name="search" />
<Stack.Screen name="search-result" />
</Stack>
);
}
Material Top Tab
import {
createMaterialTopTabNavigator,
MaterialTopTabNavigationEventMap,
MaterialTopTabNavigationOptions,
} from "@react-navigation/material-top-tabs";
import { ParamListBase, TabNavigationState } from "@react-navigation/native";
import { withLayoutContext } from "expo-router";
import { SafeAreaView } from "react-native";
const { Navigator } = createMaterialTopTabNavigator();
const MaterialTopTabs = withLayoutContext<
MaterialTopTabNavigationOptions,
typeof Navigator,
TabNavigationState<ParamListBase>,
MaterialTopTabNavigationEventMap
>(Navigator);
export default function TopTabLayout() {
return (
<SafeAreaView style={{ flex: 1 }}>
<MaterialTopTabs>
<MaterialTopTabs.Screen name="top-tab1" />
<MaterialTopTabs.Screen name="top-tab2" />
</MaterialTopTabs>
</SafeAreaView>
);
}
おわりに
タブやドロワーなどがすごく簡単に実装できていい感じです!
普段は web を開発しているので、モーダル(ページシート)が別ページなのは意外でした!
色変更などスタイルの調整も可能です!
これから、他の option や他のナビゲーションなども試していこうと思います!
(気が向いたらここにも追記します m)
Discussion