🪤

React Router v7ではreact-router-domなどがreact-routerに統合される

2024/12/21に公開

経緯

React Router v7では以下のパッケージがreact-routerに内包される様になりました。

  • react-router-dom
  • @remix-run/react
  • @remix-run/server-runtime
  • @remix-run/router

https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#package-restructuring

  • The react-router-dom, @remix-run/react, @remix-run/server-runtime, and @remix-run/router have been collapsed into the react-router package
  • To ease migration, react-router-dom is still published in v7 as a re-export of everything from react-router

遭遇したエラー

これにより、Linkコンポーネント, useLocation関数の使用箇所でそれぞれ以下のエラーが発生します。

Linkコンポーネントでのエラー

The above error occurred in the <Link> component:
    at Router (/app/node_modules/react-router-dom/node_modules/react-router/dist/development/index.js:5133:3)
    at BrowserRouter (/app/node_modules/react-router-dom/node_modules/react-router/dist/development/index.js:7209:20)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
8776 |       viewTransition
8777 |     } = _ref4,
8778 |     rest = _objectWithoutPropertiesLoose(_ref4, _excluded$1);
8779 |   let {
8780 |     basename
8781 |   } = React.useContext(NavigationContext);
                   ^
TypeError: Right side of assignment cannot be destructured
      at LinkWithRef (/app/node_modules/react-router/dist/index.mjs:8781:13)
      at renderWithHooks (/app/node_modules/react-dom/cjs/react-dom.development.js:15486:18)
      at updateForwardRef (/app/node_modules/react-dom/cjs/react-dom.development.js:19245:20)
      at beginWork$1 (/app/node_modules/react-dom/cjs/react-dom.development.js:27465:14)
      at performUnitOfWork (/app/node_modules/react-dom/cjs/react-dom.development.js:26599:12)
      at workLoopSync (/app/node_modules/react-dom/cjs/react-dom.development.js:26505:5)
      at renderRootSync (/app/node_modules/react-dom/cjs/react-dom.development.js:26473:7)
      at recoverFromConcurrentError (/app/node_modules/react-dom/cjs/react-dom.development.js:25889:20)
      at performConcurrentWorkOnRoot (/app/node_modules/react-dom/cjs/react-dom.development.js:25789:22)
      at flushActQueue (/app/node_modules/react/cjs/react.development.js:2667:24)

useLocation関数でのエラー

こちらはuseLocation自体のエラーではなくラップしていたBrowserRouterの影響の様です。

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
253 |   }
254 |   return getUrlBasedHistory(createHashLocation, createHashHref, validateHashLocation, options);
255 | }
256 | function invariant$2(value, message) {
257 |   if (value === false || value === null || typeof value === "undefined") {
258 |     throw new Error(message);
                ^
error: useLocation() may be used only in the context of a <Router> component.
      at invariant$2 (/app/node_modules/react-router/dist/index.mjs:258:11)
      at useLocation (/app/node_modules/react-router/dist/index.mjs:4780:67)
      at Header (/app/app/layouts/header.tsx:64:19)
      at renderWithHooks (/app/node_modules/react-dom/cjs/react-dom.development.js:15486:18)
      at mountIndeterminateComponent (/app/node_modules/react-dom/cjs/react-dom.development.js:20103:13)
https://discuss.rubyonrails.org/c/a-may-of-wtfs/8/l/latest      at beginWork$1 (/app/node_modules/react-dom/cjs/react-dom.development.js:27465:14)
      at performUnitOfWork (/app/node_modules/react-dom/cjs/react-dom.development.js:26599:12)
      at workLoopSync (/app/node_modules/react-dom/cjs/react-dom.development.js:26505:5)
      at renderRootSync (/app/node_modules/react-dom/cjs/react-dom.development.js:26473:7)
      at recoverFromConcurrentError (/app/node_modules/react-dom/cjs/react-dom.development.js:25889:20)

対応

react-router-domからimportしていたライブラリのインポート元をreact-routerに変更します。

- import { BrowserRouter, MemoryRouter, Link } from "react-router-dom";
+ import { BrowserRouter, MemoryRouter, Link } from "react-router";

公式のアップグレードガイドのUpdate importsセクションにも案内が書かれていました。

https://reactrouter.com/upgrading/v6

Discussion