Skip to content

Instantly share code, notes, and snippets.

@kenmori
Last active November 19, 2021 13:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenmori/56b3dbaa9f76bc574e36f7363bcea04f to your computer and use it in GitHub Desktop.
Save kenmori/56b3dbaa9f76bc574e36f7363bcea04f to your computer and use it in GitHub Desktop.
[解決] react-router-dom v5 to v6 移行に伴いやること

[解決] react-router-dom v5 to v6 移行に伴いやること

※こちらはメモ書き程度の殴り書き記事です

author

upgrade-to-react-router-v6

index

  • connected-react-routerを使っている場合修正(error TypeError: Cannot read properties of undefined (reading 'pathname') at Router (index.js:194))
  • switchをroutesに修正(言及はしてません)
  • useHistory
  • PermissionやAuthによってコンポーネントを分ける場合の修正
  • nestしたRouteをuseRoutesでどう作るか

connected-react-routerを使っている場合修正。(error TypeError: Cannot read properties of undefined (reading 'pathname') at Router (index.js:194))

error TypeError: Cannot read properties of undefined (reading 'pathname') at Router (index.js:194)

これは何かpathnameのところでエラーになっていると思ったが、実際は

connected-react-routerが出しているもの

で現状これがreact-router-dom v6に対応していない issue

解決には記事にあるように redux-first-history に変更すると動くは動くが、

ここをみながら

型定義を作るかうまいこと参照するのと、パスが redux-first-history/rr6から読み込む必要があり、ちょっとうまくいかないケースがあった(まだ検証中)

そこを変えるか

<ReactRouterDom.BrowserRouter>

単純にこれで行けた(これも今テスト中)

多分どっちかでいける。

そもそも connected-react-routerは開発が止まっているように見えるので期待しない方がいい気がしている

PermissionやAuthによってコンポーネントを分ける場合の修正

Permission.Route等権限を確認するコンポーネントでラップしている箇所

下記のこういうのを変更する

<ReactRouter.Routes>
   <ReactRouter.Route
       element={<Members.Component />}
              path={RouteEntity.RouteURI.Members} />
       <Permission.Route
             component={CompanyInfoPage.Component}
             exact
             path={RouteEntity.RouteURI.Company}/>
...

こういう風にやる

nestしたRouteをuseRoutesでどう作るか

useRoutesでネストしたchildren useRoutesにroute情報をmapした配列を渡す

[{
            path: 'a',
            element: <ReactRouterDom.Outlet />, // /aは何も表示しない場合 Outletでchildrenに処理を移らせる
            children: [
                {
                    path: ':id',
                    element: (
                        <>
                            <A.Component /> // /a/123143 で表示される
                            <ReactRouterDom.Outlet /> // /a/123143の後にpathがさらに続く場合、FragmentでラップしてOutletを入れる
                        </>
                    ),
                    children: [ 
                        {
                            path: 'edit',
                            element: <Edit.Component />
                        }
                    ]
                }
            ]
        }]
  • childrenを作る場合はoutletを含む
  • 参照

useHistory

useHistoryはuseNavigateに変更

const history = ReactRouterDom.useHistory()
const history = ReactRouterDom.useNavigate()

そして権限のところ

const Routes = () => {
    const location = ReactRouter.useLocation() // ここで画面によって権限の有無を使うようにする
    const me = ReactRedux.useSelector(AuthSelector.authProfileSelector)
    let element = ReactRouterDom.useRoutes(routes(location.pathname, me)) // routesにpathname渡す。meはauth情報が入っていると思ってください
    return element
}

routes

const routes = (path: string, me: Entity.Me | null) => {
    return Permission.isPermitted(path, profile) // ここで評価する
        ? [{path: "", element: </>}] : [ // useRoutesに渡す配列を出し分ける
              {
                  path: '/',
                  element: <NotPermitted.Component /> // ない場合NotPermittedコンポーネント
              }
          ]
})

最終

<ReactRouterDom.BrowserRouter> // 変更
  <Auth.Component>
    <Routes /> // 呼ぶ
  </Auth.Component> 
</ReactRouterDom.BrowserRouter>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment