2

I'm using react-router-redux and I have a route like this

<Route path="/user/:userId" components={{ body: UserMaintenance }} />

Whats the recommended way to load user object corresponding to the userId parameter in the route?

My thoughts (I'm new to react & redux) would be to use the userId parameter in the UserMaintenance componentWillReceiveProps method and dispatch a FETCH_USER action to the store which will load into state.currentUser. The UserMaintenance component would then update when the currentUser parameter is updated as a result of the action.

Chris Herring
  • 3,575
  • 2
  • 30
  • 48
  • 1
    Your proposition will work fine! You could also use the `onEnter` hook from the specific route: https://github.com/reactjs/react-router/blob/master/docs/API.md#onenternextstate-replace-callback – Scarysize Jul 17 '16 at 10:20
  • Cheers, looks good as mentioned below. – Chris Herring Jul 17 '16 at 12:06

2 Answers2

4

First you must decide if you want your URL to be the source of truth for the userId (I'd suggest so).

Then you know that whenever the URL/route changes, and at no other time, you will dispatch FETCH_USER.

To change user from elsewhere within the app you just browserHistory.push('/user/1234') and know that the change in URL will trigger an update to the store.

If you're happy with that, just dispatch the action in the route:

<Route
  path="/user/:userId"
  components={{ body: UserMaintenance }}
  onEnter={state => {
    store.dispatch({
      type: ACTIONS.FETCH_USER,
      key: state.params.userId,
    });
  }}
/>

If you're following this logic, you might not need react-router-redux.

Interesting comments from the author of redux over here.

Community
  • 1
  • 1
David Gilbertson
  • 3,384
  • 1
  • 18
  • 27
1

I suggest you to move that logic to Container Component that connects UserMainenance to your redux store

This would help you to separate data layer from Presentational Component that should not know anything about how to get data to render. It only needs to know how to render that data.

import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {fetchUser} from './actions';
import UserMaintenance from './UserMaintenance';

class UserContainer extends Component {
  componentWillMount() {
    const {fetchUser, userId} = this.props;
    fetchUser(userId);
  }

  render() {
    return (
      <UserMaintenance {...this.props} />
    );
  }
}

const mapStateToProps = (state, ownProps) => ({
  userId: ownProps.params.userId
  user: state.user,

});

export default connect(
  mapStateToProps, {fetchUser}
)(UserContainer);

Assuming that you have fetchUser actionCreator.

I strongly recommend you to watch Browse the Building React Applications with Idiomatic Redux course by Dan Abramov (creator of Redux) on https://egghead.io. Its free and covers this topic very well.

Dmitriy Nevzorov
  • 5,697
  • 1
  • 18
  • 28
  • Thanks. I did watch those as one of the first steps learning it all but will be worth going back over it soon now that I've actually been using it. – Chris Herring Jul 17 '16 at 12:06