Open5

React Native 開発はじめ memo

tokitoki

複数のタブのページから、特定のページにStackで遷移する

想定

  • Home, Search, Createの3ページ
  • HomeとSearchはタブから開ける
  • HomeとSearchの両方からCreateページに遷移する (Stack)

memo

  • Tabの中にStackを配置すると動く
  • Tab.ScreenとStack.Screenのnameにはページのpathを指定する
  • Stackの初期表示するページのnameの仕方は理解できてない
    • SearchStackNavigatorの1つ目のnameをsearchにするとパスが/search/searchになる
    • nameの値は、自分でつけて、initialRouteNameで指定している
    • tabで設定したpathでアクセスできる
  • Stack.Screenのnameに指定した値を元に、StackScreenのnavigationを使って遷移する
  • こうすると、/でHomeのページ、/searchでSearchのページ、/createでCreateのページになり、//searchの両方から/createがStackで呼び出せるようになる
  • Headerとかはoptions.title,options.headerShownなどを設定して修正
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import Home from "app/index";
import Create from "app/create";
import Search from "app/search";

export type RootStackParamList = {
  Index: undefined;
  Search: undefined;
  create: undefined;
};

const Tab = createBottomTabNavigator();
const Stack = createNativeStackNavigator<RootStackParamList>();

const HomeStackNavigator = () => {
  return (
    <Stack.Navigator initialRouteName="Index">
      <Stack.Screen name="Index" component={Home} />
      <Stack.Screen name="create" component={Create} />
    </Stack.Navigator>
  );
};

const SearchStackNavigator = () => {
  return (
    <Stack.Navigator initialRouteName="Search">
      <Stack.Screen name="Search" component={Search} />
      <Stack.Screen name="create" component={Create} />
    </Stack.Navigator>
  );
};

export default function RootLayout() {
  return (
      <Tab.Navigator>
        <Tab.Screen name="index" component={HomeStackNavigator} />
        <Tab.Screen name="search" component={SearchStackNavigator} />
      </Tab.Navigator>
  );
}
tokitoki

memo

  • Stack遷移先ページでタブが不要ならタブにしたいページを(tabs)などにまとめ、RootLayoutをstackにすることでも可能
  • (tabs)の外のページはStackで遷移する

  • app
    • (tabs)
      • _layout
      • index.tsx
      • search.tsx
    • _layout
    • index.tsx
    • create.tsx

app/(tabs)/_layout.tsx

import { Tabs } from "expo-router";

export default function TabsLayout() {
  return (
    <Tabs>
      <Tabs.Screen name="index" />
      <Tabs.Screen name="search" />
    </Tabs>
  );
}

app/_layout.tsx

import { Stack } from "expo-router";

export default function RootLayout() {
  return (
      <Stack>
        <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
      </Stack>
  );
}

app/index.tsx

import { Redirect } from "expo-router";

export default function Home() {
  return <Redirect href="/(tabs)" />;
}