LoginSignup
11
5

More than 5 years have passed since last update.

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

Posted at

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

  • 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というページに載っていた。

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

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

NotificationComponent.js
  componentDidMount() {
    this.fetch();
  }

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

  fetch() {
    // ...
  }

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

11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5