どうもこんにちわ
今回は、Reactのルーティングを設定する上でよく目にする
Error: Invariant failed: You should not use <Link> outside a <Router>
というエラーについて、僕自身調べてみて
Typescript中心のエラーの解決法が多いや、、。
と思ったので、シンプルなReactでの説明をしていきたいと思います。
また、解決に至るまでのプロセスで出会った3つの関数?(っていうのかな)たちも
どんどん解説していくので、ぜひ最後まで見ていってください。
まず僕がこのエラーに引っかかった時のコードかこちら、
import React from "react";
import { Link } from "react-router-dom";
export default function Home() {
return (
<div className="container">
<title>Hands on Mania</title>
<main className="u-text-center">
<h1 className="font-family-homemade">Hands on Mania</h1>
<p className="description">studying</p>
<Link to="/Auth/SignIn">signin</Link>
</main>
</div>
);
}
策① Memoryrouterを使う
最初は、react-router-domから「Memoryrouter」をインポートして
<Memoryrouter>
<Link to="/Auth/SignIn">signin</Link>
</Memoryrouter>
このようにしましょう。との解決策でした
早速試したのですが、、結果は変わらず。。
まぁまぁ焦らず、ゆっくり行こーや。
ここで解決できてたらQiitaの記事にはしてません。
では簡単に解説します。
Memoryrouterについて簡単に調べたところ、
テストおよびReact Nativeのような非ブラウザー環境で役立ちます。
と調べて一番上にあった記事で解説されていたので、
テストコードを書く時。または、ReactNative環境で普通は使うものなのかな?
と思いました。
Memoryrouterと似たような(?)ものにhooksのuseMemoが思い出されたので、
こちらも申し訳程度に紹介。
React公式によれば
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
このような公式で使い、あくまで最適化のために使うそうだ
初心者にはまだ早い領域かもしれないですね👼
策② Route と Switch を使う
こちらはgithubに乗っていた解決策だったので、
これはいけるっしょ。と内心ヨユーな表情で思っていたのですが、
あっけなく予想を裏切られました。
(僕のやり方が違う可能性が高い、、。)
方法としては、このように記述するのさっ。というやり方です。
import { Route, Switch } from "react-router";
<Switch>
<Route exact path="/Auth/SignIn" />
</Switch>
しかし、結果は儚くとも同じようなエラー内容。。
Error: Invariant failed: You should not use <Switch> outside a <Router>
だめだー、、。
俺の人生終わったー、、。
諦めないで!
そうなるのはまだ早い。
次で解決策を提示しながら一緒に解説するから、ちょっと落ち着け、モちつけ、、、、
#解決策③ (これで解決!)
import { BrowserRouter as Router, Route } from "react-router-dom";
import SignIn from "./Auth/SignIn";
<Router>
<Header />
<Route exact path="/Auth/SignIn" component={SignIn} />
</Router>
import { Link } from "react-router-dom";
<Link to="/Auth/SignIn">Signin</Link>
今回はこれで解決しました!👼
LinkとRouterをつないでいる感じですね
こちら先程の策と比べながら、今回大切にして欲しい3つのポイント
を解説していきますね。
**①react-routerとreact-router-domが似ているようでちょっと違う件について**
まず、今回import したのはreact-router-dom です。
先程はreact-routerでしたね。
これは何が違うねん!
まぁまぁ一回落ち着け、モちつけ、、、、、、(お気に入りのボケです。)
簡単な違いはというと、
react-router-domはBrowserRouterをRouterと一緒に使い、
react-routerは historyをRouterと一緒に使うということです。
詳しい解決や記述方法はreact-routerとreact-router-domこちらの記事を御覧ください!
まぁあまり大きな違いは無いようです。
② as の効果範囲
今回僕が BrowserRouter をimportする際に用いたasですが、
これの影響範囲は、例えばこの記述だと、どこまでだと思いますか?
import { BrowserRouter as Router, Route, Switch } from “react-router-dom”;
正解は、、、
Routerだけです。☆彡
以上。
③ componentsについて
<Route exact path="/Auth/SignIn" component={SignIn} />
まず、exactの記述に関して
pathに指定したルートと全く同じところに移動する感じです。
exactをつけないと違うルートに行ってしまう可能性があるためつけたほうがいいです。
componentの記述について
指定したconponentsを表示します。
今回はSignIn componentsを表示
表示したいcomponentsを import し忘れないように注意。
以上で簡単なルーティングの設定方法の解説を終わりにします。
最後に、
この記事を見る限り、v3 から v4への移行期に、色々と新しいのが出たり、
古いのが消えていたりしているそうなので、念の為、検索する際は確認してみたほうが無難かもしれないですね
react-router v3からv4へのマイグレーション
BrowserRouter
今回の参考文献【React】ルーティング設定方法