Posted at

【react-router】複数のパスで同一コンポーネント内を表示しつつ、それぞれの初期fetchを実行する方法

More than 3 years have passed since last update.

表題がわけわからないかもですが、やりたいことは



  • react-routerを使用している(今回とは関係ないけど、redux-routerも使用している)

  • ルーティングで/notifications, /notifications/unread, /notifications/officialみたいにあったときに、表示するコンポーネントは同一のものを使用したい

  • それぞれのパスで画面遷移したときに、それぞれに相応しいAPIを初期処理として呼びたい

みたいな感じです。ルーティングの設定のところは、そもそもこの書き方がイケてるのかまだわかっていないのですが、以下のような感じです


routeの設定

    <Route path='notification' component={NotificationComponent} >

<IndexRoute />
<Route path='unread' />
<Route path='official' />
</Route>


バージョン情報


  • react : 0.14.0

  • react-dom : 0.14.0

  • react-router : 1.0.0-rc1

  • redux : 3.0.2

  • react-redux : 2.1.2

  • redux-router : 1.0.0-beta3


同一のコンポーネントにしないのであれば・・・

それぞれのコンポーネントのcomponentDidMountfetchの処理をすればいいだけ


NotificationAll.js

  componentDidMount() {

store.dispatch(Actions.fetchAllNotifications())
}


NotificationUnread.js

  componentDidMount() {

store.dispatch(Actions.fetchUnreadNotifications())
}


何も考えず同一のコンポーネントにすると・・・

/notificationsから/notifications/unreadに遷移したときに、componentDidMountは呼ばれないため、fetchの処理が走らない。

または、componentDidUpdateなんかで呼び出すようにしたら、これはAPIの処理でstateを更新すると思うので、大抵の場合は無限ループになってしまう

  componentDidUpdate() {

store.dispatch(Actions.fetchNotifications())
}


react-routerComponent Lifecycleというページに載っていた。

https://github.com/rackt/react-router/blob/master/docs/guides/advanced/ComponentLifecycle.md#fetching-data

とはいえ、どういうパターンでの遷移か(子コンポーネントを表示する遷移なのかとか)でフックするイベントが異なるので思ったより複雑。

今回の自分のケースだと、


NotificationComponent.js

  componentDidMount() {

this.fetch();
}

componentDidUpdate (prevProps) {
if (prevProps.location.pathname !== this.props.location.pathname) {
this.fetch();
}
}

fetch() {
// ...
}


こんな感じで、pathを比較してるところはイケてないと思うのですが、最初にリストアップしたやりたいことはとりあえずできた