うまく動かないとき
よくつまずく症状と、その原因、直し方をまとめています。
このページの内容
リンクを押すと、ページ全体が読み込み直される
原因
リンク先のパスに、ルート表のどのパターンも合っていません。ルーターは表が答えるパスへのナビゲーションだけを引き受け、それ以外はブラウザのふつうのページの読み込みに任せます。アプリをサブパスの下で配信しているときは、サブパスの外のパスも引き受けません。
直し方
リンク先のパターンをルート表に足します。リンクをhrefで作り、Registerに表を登録しておけば、表に無いパターンは型エラーとして見つかります。
ファイルへのリンクを押すと、ファイルではなく/*のページが出る
原因
ルート表の最後にある/*は、どのパスにも合います。そのため、ホストが配るファイルへのリンクも、ルーターが引き受けてしまいます。
直し方
ファイルへのリンクにdownload属性を付けます。ブラウザがダウンロードだと知らせるので、ルーターは引き受けません。
/products/newを開くと、/products/:idのページが出る
原因
照合はルート表を上から順にたどり、最初に合ったパターンを選びます。/products/:idが先に書かれていると、newも:idに合ってしまいます。
直し方
/products/newのような決まった区間のパターンを、:idのパターンより前に書きます。
useParamsが「rendered under」という例外を投げる
原因
useParamsに渡したパターンと、そのコンポーネントがいま描かれているページのパターンが違います。いくつものページで使うコンポーネントや、レイアウトの中で呼んだときに起きます。
直し方
ページのコンポーネントの中で、そのページのパターンを渡して呼びます。いくつものページで使うなら、useRouteで型の無いparamsを読むか、useMatchで開いているページを調べます。
フレームワークの下で、useRouteやuseParamsが例外を投げる
原因
@k8ordo/staticや@k8ordo/serverでは、ブラウザにルート表も照合の結果もありません。2つのフックは<Router>が持つ照合の結果を読むので、読むものが無く例外を投げます。
直し方
ページはparamsをpropsで受け取ります。Client Componentでいまいる場所を知りたいときは、usePathnameかuseMatchを使います。
usePathnameが「needs <Router> above it」という例外を投げる
原因
サーバーでの描画やハイドレーションの間は、ブラウザのURLを読めません。そのときusePathnameは、<Router>かフレームワークのランタイムが渡すパスを読みますが、どちらも上にありません。
直し方
<Router>の下か、フレームワークが描くページの中で使います。useInterceptedNavigationで自分の仕組みを作っているときは、<PathnameProvider>で描画しているパスを渡します。
bindParamsのnavigateToで、historyのオプションが効かない
原因
パターンにparamがあると、2つ目の引数はいつもparamsとして読まれます。すべてのparamを束ねていても同じなので、2つ目に渡したオプションはparamsになり、historyは無視されます。
直し方
2つ目にundefinedを渡し、オプションは3つ目に渡します。型の検査を通していれば、2つ目に書いたオプションは型エラーになります。
遅いナビゲーションで、リンクの印が先に移る
原因
ナビゲーションではURLが先に書き換わり、新しいページは準備ができてから画面に出ます。usePathnameとuseMatchはURLを読むので、前のページが出ている間に新しいパスを返します。ブラウザのアドレスバーと同じ順序です。
直し方
読み込み中であることを見せたいときは、usePendingPathnameで読み込み中のパスを調べます。自分で始めたナビゲーションなら、navigateToのfinishedを待ちます。
React.lazyのページを読み込む間、何も表示されない
原因
errorを書いたオブジェクトは、下のページをfallbackがnullの<Suspense>で包みます。その下でReact.lazyのページがサスペンドすると、上のレイアウトの<Suspense>まで届かず、何も出ません。
直し方
同じオブジェクトにloadingを書くか、それより下に<Suspense>を置きます。
finishedがAbortErrorでrejectする
原因
そのナビゲーションが終わる前に、別のナビゲーションが始まりました。追い越されたナビゲーションは中断され、finishedは中断の理由でrejectします。
直し方
追い越されうる場所でfinishedを待つときは、名前がAbortErrorのDOMExceptionだけを無視し、ほかのエラーは投げ直します。
ボタンを押すたびに、ページ全体がクロスフェードする
原因
<ViewTransition>が、ページの切り替え以外のtransitionでも動いています。@k8ordo/uiのButtonのアクションの実行中も、transitionです。
直し方
<ViewTransition>のdefaultをnoneにし、updateに{ navigation: 'auto', default: 'none' }を渡します。ルーターが付けるnavigationの種類のときだけ動くようになります。
検索の条件を変えても、エラーの表示が消えない
原因
ルート表のerrorの表示は、別のページに移ったときに消えます。クエリ文字列だけを変える状態の更新はページの切り替えではないので、表示は残ります。
直し方
errorのコンポーネントが受け取るresetを呼ぶと、その場でページを描き直します。
Registerに登録したのに、表に無いパターンが型エラーにならない
原因
登録を書いたファイルが、TypeScriptの検査の対象に入っていません。フレームワークの下では、.k8ordoがドットで始まるため、tsconfig.jsonのincludeにディレクトリの名前だけを書くと読み飛ばされます。
直し方
登録を書いたファイルをincludeの範囲に置きます。フレームワークの下では、includeに.k8ordo/**/*.tsのグロブを書きます。