TypeScript で react-router + Redux を使う(mapStateToProps編)
react-router と Redux を組み合わせるときは、withRouter を使うことでコンポーネントに history や location (URLパスやクエリ) などを渡すことができる。
それを Redux の mapStateToProps でゴニョゴニョすることでURLパスやクエリとStoreのデータを組み合わせることができる。
その際、mapStateToProps = (state, props) => {...} の props にどのような型をつければいいか調べたのでメモ
TL;DR
RouteComponentProps を使う。
使い方
通常のURLの場合、RouteComponentProps<{}> とする。
"/users/:userId" のような形で、URL内にユーザーIDなどのパラメータがある場合、RouteComponentProps<{userId: string}> のように、パラメータの型を引数に与える。
import { connect } from 'react-redux' import { RouteComponentProps, withRouter } from 'react-router-dom' // URLにパラメータがない場合 const mapStateToProps = (_, props: RouteComponentProps<{}>) => { console.log(props) return { ... } } // URLにパラメータがある場合 const mapStateToProps = (_, props: RouteComponentProps<{userId: string}>) => { console.log(props) return { ... } }
解説
react-router の index.d.ts を抜粋すると以下のようになっている。
import * as H from 'history'; export interface RouteComponentProps<P, C extends StaticContext = StaticContext> { history: H.History; location: H.Location; match: match<P>; staticContext: C | undefined; } export interface match<P> { params: P; isExact: boolean; path: string; url: string; }
この RouteComponentProps が、 withRouter が渡す引数の型とドンピシャなのでこれを使う。
よくみると第一引数 P を match<> に渡しており、この P でURLパラメータの型を指定できる。