Open6

RemixからReact-Routerにアップグレードした

secchanusecchanu

importの置き換えはアップグレードガイドにあるcodemod利用した

secchanusecchanu

設定ファイルとか

最終的に主に変える必要あったもの
以降で特に触れてないものは新しく用意したものにカスタマイズしてた部分反映させただけ(lang="ja"とかフォントとか)

新規作成

  • routes.ts
  • react-router.config.ts
  • vite.config.ts

変更

  • root.tsx
  • tsconfig.json
  • package.json(当たり前だけどscriptsの修正漏れてて最初動かなかった)

削除

  • entry.client.tsx
  • entry.server.tsx
  • remix.config.js
secchanusecchanu

各ページ

json

loaderやactionで返す時にjson()使っていたけど廃止されたので外した
特殊な値入れてなければ外すだけで良いはず

APIとして使っているところはResponse.json()に置き換えた

Using props

routes.tsの定義から自動的に型生成してくれるのでRouteから取る

import type { Route } from "./+types/route-name";

export default function MyRouteComponent({
  loaderData,
  actionData,
  params,
  matches,
}: Route.ComponentProps) {
  return (
    <div>
      <h1>Welcome to My Route with Props!</h1>
      <p>Loader Data: {JSON.stringify(loaderData)}</p>
      <p>Action Data: {JSON.stringify(actionData)}</p>
      <p>Route Parameters: {JSON.stringify(params)}</p>
      <p>Matched Routes: {JSON.stringify(matches)}</p>
    </div>
  );
}

useLoaderDataとかもそのまま使えるので急いで変える必要はなさそう(自分は勢いで全部変えたけど)

secchanusecchanu

挙動が変わったところ

loaderの実行タイミング

Remixの時は必要な時だけloaderが実行されていたが、React-Routerでは基本的に関係するloaderは毎回全部実行される
Nested Routesの中で移動していると毎回親のloaderが呼ばれる感じ

これはSingle Fetchの仕様で、複数のloaderを単一のリクエストで呼ぶようになったから

Single Fetch自体はサーバーとのやり取り減って良いなと思うけど、何も考えずに移行しちゃうと思っていたよりAPI叩いてるみたいなことにもなりかねないかも

今までの動作に戻すなら以下を追加するのが一番簡単

export function shouldRevalidate() {
  return false;
}

それ以外だとキャッシュの仕組み整えてもろて…

NavLink(Link)から飛んだ先のloaderで別ドメインにリダイレクトする処理が動かなくなった
別タブで開くと正常な動作するけど、クライアントサイドルーティングと干渉してるかも?
とりあえずの解決策としてNavLink(Link)をaタグに置き換えると動作した