Skip to content
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

Make "key" optional for performance #97

Closed
ryanflorence opened this issue Jul 21, 2014 · 18 comments · Fixed by #229
Closed

Make "key" optional for performance #97

ryanflorence opened this issue Jul 21, 2014 · 18 comments · Fixed by #229
Labels

Comments

@ryanflorence
Copy link
Member

Right now we assign a key to a handler so that transitions from /users/1 to users/2 rerenders as expected without any extra work for the developer. However, we cause react to build up brand new dom with that transition.

I would like to do something like <Route useKey={false}/> or Router.disableKeys().

This would require devs to implement componentWillReceiveProps on their route handlers when transitioning from /users/1 to /users/2, but they will also get some perf improvements if they feel like they need them.

Thoughts?

@sophiebits
Copy link
Contributor

If we make data fetching part of the router by default, I'd push for not assigning keys by default since components will be purer by default and the router can take care of re-fetching and passing the new data down (which is the logic that you normally might have in a componentDidUpdate).

@brigand
Copy link
Contributor

brigand commented Jul 24, 2014

This one has been biting me a bit, because I have a scrolling list on the left, and the details for the selected item on the right.

I need the url to update when you click a new item, which works, but then the list on the left is scrolled back to the top because the dom was thrown out. In reality, all that's changed is the text content of ~10 elements on the right hand side.

@ryanflorence
Copy link
Member Author

yeah thats 👎 and exactly the case where this option would be 👍

@mjackson
Copy link
Member

Why don't we just make this a static method of the route handler? Default behavior would be to use no key, but the user could provide a getRouteKey(params, query) method that they could use to generate a key for that route if they want.

@sophiebits
Copy link
Contributor

Since users call activeRoute manually now, they can already pick a key themselves if they want.

@brigand
Copy link
Contributor

brigand commented Jul 24, 2014

Wow, thanks @spicyj. That fixed my UX problem.

In that case, it should just be a note in the README if anything.

@ryanflorence
Copy link
Member Author

@spicyj and I have talked in irc about this a bit. When #57 is all sorted out, the implementation there may make it so we can just remove keys altogether.

The reason we have them is to transition from and to the same route with different params; if we prescribe a convention around providing data, we will necessarily implement the hooks that will cause the view to update (w/o needing keys).

@ryanflorence ryanflorence added this to the v1.0 milestone Jul 27, 2014
@ryanflorence
Copy link
Member Author

<Routes useAutoKeys={false}/>

?

@sophiebits
Copy link
Contributor

Flags that change how the entire application behaves are hard to reason about, especially if the default allows you to be sloppier when writing the original code – when you switch the flag later on you'll have no idea what will break. I don't have a great idea for a better plan here though. Perhaps now that AsyncState exists we can encourage using that and never add keys?

@ryanflorence
Copy link
Member Author

alright, will reopen if we head down that path and decide to come back to discuss this some more.

@ryanflorence
Copy link
Member Author

reopening, I'm starting to think we should not be doing anything with keys.

@ryanflorence ryanflorence reopened this Aug 14, 2014
@mjackson
Copy link
Member

Why not? I honestly have no idea.

@ryanflorence
Copy link
Member Author

We added the key in because a transition from /users/1 to /users/2 doesn't do anything unless you implement componentWillReceiveProps. At the time, we were react newbies and thought "that sucks!" so we added keys and were happy that everything worked.

My only concern is getting lots of tickets around "transitioning to the same route is broken". I guess we can just make it loud and clear in the README, examples, docs, everywhere, that you need componentWillReceiveProps when you are using dynamic segments.

@mjackson
Copy link
Member

Ah, now I remember.

Can we do something fancy with shouldComponentUpdate? Maybe something like:

shouldComponentUpdate: function (nextProps, nextState) {
  return compareParams(this.props.params, nextProps.params);
}

?

@sophiebits
Copy link
Contributor

Yay! I don't think shouldComponentUpdate helps here though.

@gaearon
Copy link
Contributor

gaearon commented Aug 17, 2014

I think it's fair to have people implement componentWillReceiveProps because it perfectly mirrors what happens when you pass a different value were you to implement routing yourself. Moreover if you don't want behavior, it's trivial to give your route handler a key yourself and opt-in to full replacement, just like in normal React code. I'd like to see keyless as default.

@machty
Copy link

machty commented Aug 25, 2014

Not sure if this is possible in React but one thing that might be helpful would be to warn if, for a route that introduces a new param relative to its ancestors, componentWillReceiveProps hasn't been defined.

ryanflorence added a commit that referenced this issue Aug 26, 2014
gimme some of that sweet, sweet DOM diffing

closes #97
@ryanflorence
Copy link
Member Author

follow #229

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

Successfully merging a pull request may close this issue.

6 participants