はじめに
react router を使ってルーティングする際、込み入ったデザインだとコンポーネントを跨いでタグを配置することになります。
自分はそこで少し躓いてしまったので、誰かの役に立つのではと思い記事に残してみました。
まず、<Link>を直接<BrowserRouter>の中に書くことができる場合
App.tsx
import { Sidemenu } from "components/organisms/Sidemenu";
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
function App() {
return (
<Sidemenu />
<main>
<BrowserRouter>
<Routes>
<Route path="/" element={<Top />} />
<Route path="SubPage" element={<Subpage />} />
</Routes>
<Link to="/">
トップページ
</Link>
<Link to="/SubPage">
サブページ
</Link>
</BrowserRouter>
</main>
);
}
このパターンなら、各サイトに似た構成の解説が載っているため、初心者の私たちでも実装できます。
ただここで上司から、
<Sidemenu />コンポーネント内に<Link>を移動させてほしい
という指示が飛んできたとしましょう。
<Link>が別コンポーネントにある場合
App.tsx
import { Sidemenu } from "components/organisms/Sidemenu";
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<Sidemenu />
<main>
<BrowserRouter>
<Routes>
<Route path="/" element={<Top />} />
<Route path="SubPage" element={<Subpage />} />
</Routes>
</BrowserRouter>
</main>
);
};
Sidemenu.tsx
import { Link } from 'react-router-dom';
export const Sidemenu = () => {
return(
<Link to="/">
トップページ
</Link>
<Link to="/SubPage">
サブページ
</Link>
);
}
はい、もう動きませんね😢
ちなみにエラーはこんなかんじ
Uncaught Error: useHref() may be used only in the context of a <Router> component.
とか
The above error occurred in the <Link> component:
など
ただこれだけのことだった
App.tsx
import { Sidemenu } from "components/organisms/Sidemenu";
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Sidemenu />
<main>
<Routes>
<Route path="/" element={<Top />} />
<Route path="SubPage" element={<Subpage />} />
</Routes>
</main>
</BrowserRouter>
);
};
ルーティングに関わる要素を<BrowserRouter>で囲めば済む話でした
ついつい初心者の私たちは間違った固定概念を持ってしまいがちです。
今回の場合でいうところの
😠「<BrowserRouter>の直下には<Routes>が存在しないといけないんだ!」
という思い込みですね。
↑さっきまでの私
自分はこれを解決するのに1時間以上の時間をかけてしまいました。
意外とこのシチュエーションの記事は無かったので、
(初歩のミス過ぎてみんな書かないだけかも)
もしよろしければ参考にしてみてください。
※なにか間違っている部分があればご教示いただけると幸いです。