Skip to content

componentWillReceiveProps: how to know when dynamic segment changes? #584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ruggeri opened this issue Dec 10, 2014 · 9 comments
Closed

Comments

@ruggeri
Copy link

ruggeri commented Dec 10, 2014

tl;dr: what is the recommended way in componentWillReceiveProps to find the previous dynamic segment?

Longer:

I understand the note about dynamic segments: the lifecycle hook to fetch data when a dynamic segment changes is componentWillReceiveProps. Cool.

In React, componentWillReceiveProps receives as an argument the nextProps. These can be compared to this.props and used to determine whether a relevant property changed and data should be fetched.

What I want to do is only fetch new data in componentWillReceiveProps if the dynamic segment changes. Significantly, in the presence of other props, I cannot assume that componentWillReceiveProps is called only when the dynamic segment changes. However I haven't found a way to recover the previous routing params.

I can easily work around by setting an instance variable in componentWillReceiveProps to record the current routing params for comparison on the next invocation of componentWillReceiveProps. That seems sort of nasty and stateful.

I hope I haven't misunderstood. But if I have understood correctly, then the routing params context is mutable and the previous route is lost, and cannot be compared against. That seems contrary to the concept of componentWillRecieveProps.

@ruggeri
Copy link
Author

ruggeri commented Dec 10, 2014

To be clearer, right now I feel like I have to write something like this in my components:

var MyComponent({
  componentWillReceiveProps: function () {
    if (!_.isEqual(this._prevParams, this.getParams())) {
      this._prevParams = _.clone(this.getParams())
      this.fetchSomeData()
    }
  }

  // ...
});

@abergs
Copy link
Contributor

abergs commented Dec 17, 2014

I ran into this too when upgrading the router. We had to solve it in the same way. Perhaps a better way would be to introduce a this.getPrevParams()?

@gaearon
Copy link
Contributor

gaearon commented Dec 17, 2014

I usually do this:

parseUserId(props) {
  return parseInt(props.params.userId, 10);
},

componentWillReceiveProps(nextProps) {
  var userId = this.parseUserId(this.props),
      nextUserId = this.parseUserId(nextProps);

  if (userId !== nextUserId) {
    this.userWillChange(nextUserId);
  }
},

userWillChange(userId) { ... }

Why do you need to save previous params?

@abergs
Copy link
Contributor

abergs commented Dec 18, 2014

@gaearon I don't thank that works with latest react-router? We mean comparing the last props.params.userId with nextProps.params.userId

@gaearon
Copy link
Contributor

gaearon commented Dec 18, 2014

Why wouldn't it? But you're right, I meant props.params.


@abergs I fixed the example.

@gaearon
Copy link
Contributor

gaearon commented Dec 18, 2014

@abergs But you are still free to pass them to route handlers if you like. (I do.)

e.g.

  router.run((Handler, state) => {
    RouterActionCreators.changeRoute(state);
    React.render(<Handler {...state} />, document.body); // this will pass query, params, like before
  });

and later

return <RouteHandler {...this.props} />

in nested handlers.

This'll give you familiar params, query on each route handler as long as you don't forget to pass them.

@gaearon
Copy link
Contributor

gaearon commented Dec 18, 2014

Another way do to the same is to follow last comment in example you linked to:

// Also, if you're using a flux-style app, you can trigger a "transition"
// action in the `run` callback with the params/query in the payload, then
// subscribe in your handlers to the store that grabs the data.

@ryanflorence
Copy link
Member

see #579 (comment)

@lock lock bot locked as resolved and limited conversation to collaborators Jan 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants