火曜日, 4月 29, 2025
Google search engine
ホームニューステックニュースReact Router v7へ移行した

React Router v7へ移行した


業務でReact Router を使っていて最近移行したので実際に移行の際に実施したことをまとめます!

前提
React Router のバージョン:6.23.1

以下の順で移行を進めました

  1. v6の最新までアップデート
  2. v7にアップデート

こちらのChangelogを調べて、破壊的変更(Breaking Change)がないか確認しました。
特になかったのでv6.30.0までアップデートしました。

https://reactrouter.com/changelog

https://developers.prtimes.jp/2024/12/24/react-router-v7-upgrade/#index_id1

上の参考記事ではv7のfutureフラグを使用して段階的に移行していましたが、私が所属するチームのコードではfutureフラグで影響がある箇所がなかった為一気にv7まで上げました。

🔍 v7のfutureフラグで影響があるか調べた内容

v7_relativesplatpath

dashboard/* (単なる * ではなく) のような複数セグメントのスプラットパス(* を含むパス)の相対パスのマッチングとリンクを変更します。

を 2 つに分割する

コードにあったcreateBrowserRouterは単なる*でしたので対象外でした。

const router = Router.createBrowserRouter([
	{
		path: "*",
		Component: () => (
			AxiosProvider>
				Sentry.ErrorBoundary fallback={({ error }) => Error error={error} />}>
					AppRoot />
					Router.ScrollRestoration />
				/Sentry.ErrorBoundary>
			/AxiosProvider>
		),
	},
]);

相対リンクを更新する

相対パスではないので対象外でした。

Link
       to="https://www.immedio.io/sample"
       target="_blank"
~~~~~~~
Link
       to="https://www.immedio.io/sample2"

v7_startTransition

React.lazy がコンポーネント外部で定義されているので対応不要でした。

v7_fetcherPersist

useFetchersを使用している記述がないので対応不要でした。

v7_normalizeFormMethod

formMethodの記述がないので対応不要でした。

v7_partialHydration

fallbackElement を実装していないので対応は不要でした。

v7_skipActionErrorRevalidation

async function actionの記述がないので対応は不要でした。

非推奨

json および defer メソッド

jsonメソッドはネイティブのものしかないので対応不要でした
deferメソッドは実装していないので対応不要

🚧 react-routerをv7にアップデートを実施

ライブラリをinstall

  • react-router-dom@latestをinstallする
  • react-router-domをuninstallします

react-routerのインポートを更新する

コマンドで一括置換できます
以下はdocumentにあるサンプルのコマンドです

find ./path/to/src \( -name "*.tsx" -o -name "*.ts" -o -name "*.js" -o -name "*.jsx" \) -type f -exec sed -i '' 's|from "react-router-dom"|from "react-router"|g' {} +

DOM 固有のインポートを更新する

RouterProvider と HydratedRouter は、”react-dom” に依存するため、深いインポートから取得されます。

-import { RouterProvider } from "react-router-dom";
+import { RouterProvider } from "react-router/dom";

おまけ tsconfigの設定を修正

修正した経緯

react-router-router/domの型定義ファイルの形式がmtsでした。
tsconfigのmoduleResolutionがnodeの為、深いimportができませんでした。

moduleResolutionnodeから bundlerへ、allowImportingTsExtensions:trueを追加しました。

{
  "compilerOptions": {
    "target": "es6",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "allowImportingTsExtensions":true,
    "noEmit": true,
    "jsx": "react-jsx",
    "types": ["vite/client"],
    "jsxImportSource": "@emotion/react",
    "baseUrl": "./src",
    "paths": {
      "~/*": ["./*"]
    }
  },
  "sourceMap": true,
  "inlineSources": true,
  "sourceRoot": "https://zenn.dev/",
  "include": ["src"]
}

修正するまでの過程

Cannot find module ‘react-router/dom’ or its corresponding type declarations.
There are types at ‘/Users/yamanetaisei/dev/immedio/node_modules/react-router/dist/development/dom-export.d.mts’, but this result could not be resolved under your current ‘moduleResolution’ setting. Consider updating to ‘node16’, ‘nodenext’, or ‘bundler’.

tsconfigのmoduleResolutionをnodenext、moduleをNodeNextにすると、

Relative import paths need explicit file extensions in ECMAScript imports when ‘–moduleResolution’ is ‘node16’ or ‘nodenext’. Did you mean ‘./util/errors.js’?

An import path can only end with a ‘.ts’ extension when ‘allowImportingTsExtensions’ is enabled.

allowImportingTsExtensionsをtrueにすると、moduleResolutionをbundler,noEmitかemitDeclarationOnlyを設定する必要がある

Allow imports to include TypeScript file extensions. Requires ‘–moduleResolution bundler’ and either ‘–noEmit’ or ‘–emitDeclarationOnly’ to be set.

useNavigateが非同期になったことによる影響調査

useNavigateが使われている周辺コードを確認しましたが、画面遷移とあわせてスナックバーを表示するのみなので影響はないと判断しました。

useNavigateは以下の場合にawaitにする必要があります。

  • 画面遷移後に続けて実行したい操作がある場合(inputにフォーカスあてるなど)
  • 画面遷移先のページにloader, actionがあり、そのエラーハンドリングを行いたい場合

ページ遷移に関わる処理でしたが、無事に問題なく移行できました!

フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -
Google search engine

Most Popular