Question: What are some alternatives to componentDidMount for registering store listeners and invoking actions on route transition?

Question

What are some alternatives to componentDidMount for registering store listeners and invoking actions on route transition?

Answers 1
Added at 2016-05-06 23:05
Tags
Question

Say I have a user profile component being served by a react-router route.

//RouteStrings is just an object which defines my constant string values

<Route name={ RouteStrings.userEdit.name }
       path={ RouteStrings.userEdit.path }
       component={ UserEdit } />

In the path definition, a userid parameter is used to load the current user in the componentDidMount function.

//RouteStrings constants file
//an applyPath function is used to place parameters into the path string
userEdit: {
  name: 'userEdit',
  path: '/user/:userid/edit',
}

//UserEdit component
componentDidMount() {
    this.unsubscribe = UserStore.listen(this.onStatusChange.bind(this));
    //loadPersonById is a reflux action that resolves asynchronously and
    //eventually updates the state of the component to trigger a rerender
    UserActions.loadUserById(this.props.params.userid);
}

componentWillUnmount() {
    this.unsubscribe();
}

onStatusChange(state) {
  this.setState(state);
}

But, now, introduce the idea that an administrator can edit other users' profiles as well as their own.

Currently, if an administrator is editing the profile of another user, and then directly attempts to route to their own profile, the userid parameter changes correctly. However, the component is not unmounted and remounted to trigger another profile load, meaning the content on the page reflects that of the old user's profile rather than the administrator's.

I've run into this issue a few times now and have been using workarounds with query strings and willReceiveProps. I fear that my use of react-router / reflux is archaic.

My question(s):

  • Should I be using something besides componentDidMount to register store listeners?
  • How can I fix this issue without repeating calls to my load function?

    • I tried the idea of having two routes -- one which serves your own profile, and one which serves other users' profile for administration only. However, this leads to a huge refactoring issue where every time a user's image or profile link occurs throughout the app, a check has to be done to decide if it should route to the "own profile" version, which could possibly work but seems unnecessarily tedious.
    • As has been answered many times, the solution is not to force react-router to rerender the component, but rather to trigger a state change.
Answers to

What are some alternatives to componentDidMount for registering store listeners and invoking actions on route transition?

nr: #1 dodano: 2016-05-06 23:05

Should I be using something besides componentDidMount to register store listeners?

Use componentWillMount when you can. The difference being that WillMount is called before the initial render, while DidMount is called after.

If you need to call that logic again, instead of writing it in a lifecycle function, write in a component method and call it where you need to.

instead of

componentDidMount() {
    this.unsubscribe = UserStore.listen(this.onStatusChange.bind(this));
    UserActions.loadUserById(this.props.params.userid);
}

you can do

componentWillMount() {
    this.loadUserById(this.props.params.userid);
}
componentWillReceiveProps(nextProps) {
    if (this.props.params.userid !== nextProps.params.userid) {
        this.loadUserById(nextProps.params.userid);
    }
}
loadUserById(id) {
    this.unsubscribe = UserStore.listen(this.onStatusChange.bind(this));
    UserActions.loadUserById(id);
}

with whatever other logic to clean up when changing user IDs.

Source Show
◀ Wstecz