動画教材でreact-router-domでルーティングをするという課題をやる
環境は教材はv5、自分はv6
v6で相対パスにしたくて、ネストで引っかかったのでメモ
やりたいこと
- ルーティングをネスト表示したい
- Page1DetailA(Page1の子コンポーネント)を表示した際はPage1コンポーネントは非表示にしたい(ネスト表示する前と合わせたい)
まずはネスト前のコード
この場合、Page1DetailAに移動してもPage1は表示されない
※パスは絶対パス
<BrowserRouter>
<div>
<Link to='/'>Home</Link>
<Link to='/page1'>Page1</Link>
<Link to='/page2'>Page2</Link>
</div>
<Routes>
<Route exact path='/' element={<Home />} />
<Route path='/page1' element={<Page1 />} />
<Route path='/page1/detailA' element={<Page1DetailA />} />
<Route path='/page1/detailB' element={<Page1DetailB />} />
<Route path='/page2' element={<Page2 />} />
</Routes>
</BrowserRouter >
Page1DetaiAの表示
ネストしてみる
- Page1内のルート(detailAやdetailB)を親のPage1の下にネスト
- 相対パスに変更
<BrowserRouter>
<div>
<Link to='/'>Home</Link>
<Link to='/page1'>Page1</Link>
<Link to='/page2'>Page2</Link>
</div>
<Routes>
<Route exact path='/' element={<Home />} />
<Route path='/page1' element={<Page1 />} >
<Route path='detailA' element={<Page1DetailA />} />
<Route path='detailB' element={<Page1DetailB />} />
</Route>
<Route path='/page2' element={<Page2 />} />
</Routes>
</BrowserRouter >
また、子コンポーネントを表示させるために
- Outletをインポート
- Page1の中に
<Outlet />
を置く - パスを相対パスに変更する
import { Link, Outlet} from "react-router-dom"
export const Page1 = () => {
return (
<>
<h1>Page1です</h1>
<Link to='detailA'>DetailA</Link>
<Link to='detailB'>DetailB</Link>
<Outlet />
</>
)
}
Page1DetaiAの表示
結果、ネストしたことでPage1DetaiAの表示が変わってしまう
親コンポーネントを表示させたくない場合、
ネストせず絶対パスで対応すれば良いが、せっかくなのでネストした状態で表示できないかやってみた
解決策:useLocationを使用
useLocation
のpathname
で現在のURLが取得できる。
現在のURLが/page1
ではない場合、<Outlet />
をレンダリングして子ルートのコンテンツを表示
修正コード
-
useLocation
でパスを取得 - パスの条件でレンダリングを行う
/page1
でないときに<Outlet />
をレンダリング
import { Link, Outlet, useLocation } from "react-router-dom"
export const Page1 = () => {
const location = useLocation();
if (location.pathname !== '/page1') {
return <Outlet />
}
return (
<>
<h1>Page1です</h1>
<Link to='detailA'>DetailA</Link>
<Link to='detailB'>DetailB</Link>
<Outlet />
</>
)
}