【Expo Router】存在しないルートを参照しているときに出るWarnings
[Layout children]: No route named "foo" exists in nested children: ["(tabs)", "modal"]
[Layout children]: Too many screen defined. Route "foo" is extraneous.
「存在しないRouteを参照する」を具体的に言い換えると、「_layout.tsxにおいて、同階層のファイルまたはディレクトリ名として存在しないnameを持つスクリーンの定義をする」こと
<Stack.Screen name="hoge"></Stack.Screen>と書いたが"hoge"という名前のファイルまたはディレクトリが存在しないという状況
ユーザ側からするとどちらのwarningも同じミスによって起きる
どこで不正なScreenを定義しているかによってどちらになるかが変わる
このあと示す例ではStack Screenを利用しているが、Tabs Screenでも同様
説明に使う例:
(tabs)というディレクトリと、modalというファイルが配置されている
(tabs)の中身は省略
よって、_layout.tsx内のScreen定義で参照できるroute nameは"(tabs)"かmodalのみ
code:ディレクトリ構造
.app/
├── (tabs)/
├── _layout.tsx
└── modal.tsx
code:app/_layout.tsx
import { Stack } from 'expo-router';
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
</Stack>
);
}
意図的にwarningを出してみる
1. No route named "foo" exists in nested children
存在しない route name を持つ Screen を定義する(末尾以外の場所)
code:app/_layout.tsx.diff
import { Stack } from 'expo-router';
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
+ <Stack.Screen name="foo" options={{ headerShown: false }} />
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
</Stack>
);
}
code:warning
存在しないRouteを参照するScreenがあるためwarning
2. Too many screen defined.
存在しない route name を持つ Screen を、Stack内の最後で定義する
code:app/_layout.tsx.diff
import { Stack } from 'expo-router';
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
+ {/* <Stack> のchildrenの最後に定義 */}
+ <Stack.Screen name="foo" options={{ headerShown: false }} />
</Stack>
);
}
code:warning
ScreenとRouteを紐付け終わったにも関わらずScreenが定義されているためwarning
expo-routerの該当実装箇所