React Router から渡される match
, location
, history
プロパティ(Route props)を使用する3通りの方法です。(3番目の方法はあまり知られていないはず)
1. Route コンポーネントでレンダリングする
Route コンポーネントのレンダリング方法は componentプロパティ
, renderプロパティ
, childrenプロパティ
の3つがありますが、いずれの方法でも Route props が渡されます。
以下のHogeコンポーネントは、いずれも Route props を使用できます。
const Hoge = props => {
const { match, location, history } = props;
...
}
<Route path="/hoge" component={Hoge} />;
<Route path="/hoge" render={routeProps => <Hoge {...routeProps} />} />;
<Route path="/hoge" children={routeProps => <Hoge {...routeProps} />} />;
2. withRouter を使う
withRouter
HOC を使えば、Route コンポーネントでレンダリングしたコンポーネントではなくとも任意の場所で Router props を使用できます。
(ただし、 withRouter
は location の変更等を関知しないので、注意が必要です。 )
import { withRouter } from "react-router";
const Hoge = withRouter(props => {
const { match, location, history } = props;
...
})
const Container = () => (
<div>
<Hoge />
</div>
)
3. RouteContext を使う
1,2 はおさらいで、ここからが本題です。
react-router
には __RouterContext
というものがあり、これにより Route props を取得することが出来ます。
ちなみに、下記のようにカスタム hook にしておくと便利だと思います。この hook を使えば下層のコンポーネントでも手軽にRoute props を取得できます。
ただし、 __RouterContext
という名前から感じるように本来は触らないほうがいいものかもしれませんので、使用は自己責任で。
import {
__RouterContext as RouterContext,
RouteComponentProps,
} from 'react-router'
const useRouter = (): RouteComponentProps =>
React.useContext(RouterContext) as RouteComponentProps
const Hoge = () => {
const { match, location, history } = useRouter()
...
}
2019-09-27 追記
React Router の v5.1 がリリースされ、 useHistory
, useLocation
, useParams
, useRouteMatch
の hooks が正式に提供されました。詳細は下記ページが詳しいです。