やりたいこと
React Routerを使うに当たり、遷移先に値を送信したい。
<li>
<Link to={{pathname: "/users/mypage/recommends", state: {books: this.state.books}}}>
推薦図書一覧
</Link>
</li>
公式を見る限りこのようにstateというキーを使うことで値を送ることができるっぽい
しかし、ここで問題になるのが送った値を遷移先でどう受け取るか、という話。
ルーティングは以下のように設定してある
<Route path="/users/mypage">
<MyPage>
<Route exact path="/users/mypage">
<UserInfo></UserInfo>
</Route>
<Route path="/users/mypage/recommends">
<MyRecommendedBooks></MyRecommendedBooks>
</Route>
<Route path="/users/mypage/edit">
<EditUserInfo></EditUserInfo>
</Route>
</MyPage>
</Route>
サイドバーにリンクを設定して同一ページ内で表示を切り替えるような実装をしている。
検討したこと
withRouterを使う
調べた限りclassコンポーネントだとwithRouterを使うことでlocation.state.books、のようにlocationプロパティを扱うことが
できるようになるらしい。
しかし今回はサイドバーで表示の切り替えをするだけなので全部のコンポーネントをクラスコンポーネントで扱うのは面倒。
結論…useLocation()を使おう
React Hooksの1種useLocationを使うとかんたんに関数コンポーネントでlocationプロパティを扱える
// react-routerの読み込み
import { Link, withRouter, useLocation } from "react-router-dom";
export function MyRecommendedBooks() {
const location = useLocation();
if (location.state.books.length !== 0) {
return (
<ul>
{location.state.books.map(book => {
return <li key={book.isbn}>{book.title}</li> //returnがないと表示できない
})}
</ul>
)
} else {
return null
}
}
こんな感じでモジュールをimportして、関数内でuseLocation()とするだけでlocationプロパティにアクセスできた。すげぇ便利だ…
後は先程のリンクで定義したstateを取り出してビューにレンダリングするだけ。
挙動
こんな感じでサイドバーのリンクをクリックすると同時にビューにDBから取り出した値を表示できた
参考
React-Router公式
https://reactrouter.com/web/api/Link
qiita記事
https://qiita.com/h-yoshikawa44/items/aa78b6c7cd1ef43549bf