-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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 react-router-redux work with time travelling #4717
Conversation
}) | ||
// Dispatch LOCATION_CHANGE except when we're in time travelling | ||
if (!this.inTimeTravelling) { | ||
store.dispatch({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, will this trigger the same problems as #4713?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. So, my idea is going to refactor it to listen the history in the constructor and dispatch it in the listener instead (actually, the same approach I did here).
I actually don't think that issue is going to change anything. |
@mjackson I think if we know the history index which provided by a listener, we can use |
@supasate Yep, that was my original theory. But I still don't think that issue is going to change anything. |
@mjackson Can we leave that issue to solve later when there is appropriate APIs or alternative ideas? I'd also like to get feedback on the following issue.
|
In the current PR, It would be an issue when we want to address supasate/connected-react-router#36. I don't see other solution for that than described in zalmoxisus/redux-devtools-instrument#15 (comment). Relying on |
@supasate I just made some big changes on the ConnectedRouter. It now relies on a history listener, rather than "subscribing" via This will need a bit of a refactor then. My general plan is to copy most of what we did with 4.0.8, so we can handle rewinds and let users decide if the URL bar should update or not. |
8d2fb58
to
f32f172
Compare
f32f172
to
4de9ef5
Compare
@timdorr I rebased the code and now made it pass the Devtools test cases (by adapting your 4.0.8 about firing initial location again if the store is reset). I don't understand all your code yet, so, I tried to simplify it and might miss some cases, please advise if you find anything went wrong. |
@timdorr is there any update on this issue? |
Nope, I'm busy on a side project that has a deadline of next Friday (worst case scenario). I hope to have some time for OSS coding soon! |
Understandable! No rush. Take your time! |
Is there any updates on this amazing feature? |
ping @timdorr |
Pong! Sorry, I've been turbo busy lately with a new product release. I'm going to be switching jobs next month, and have some time taken off between them where I'll devote some time to this and other projects. |
// Store will be updated to initial location in handleLocationChange. | ||
this.props.history.push(this.initialLocation) | ||
} else { | ||
this.props.history.push(storeLocation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is going to break the browser's history. You cannot just push
the location onto the history stack because this will create a new entry in the history. This means you're always going forward in the history, even if the intent was to go back.
What you really need to do here is history.go(n)
where n
is the difference in the index of the current location in the history and the index of the storeLocation
, or the location you want to get to. But as much as I've tried to think about it over the years, I can't figure out a reliable way to get that n
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mjackson In Hickory, instead of using random keys I use incremental values of major.minor
where major increments when pushing and minor increments when replacing. Then, determining n
is just a matter of parsing the keys for the two locations and calculating the difference between majors.
Perhaps I overlooked something when implementing that, but I haven't thought of any reason that that shouldn't work.
I should note that I took the easy route and always use window.history
so that I can rely on state, even with hash history. Decided to just support IE10+ and newish Android. http://caniuse.com/#feat=history
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if we could always rely on state then we could do it for sure. You're right, we should just do that. I need to stop thinking about supporting old browsers.
Hey guys, Any progress on this? P.S. Love your work! Thank you so much 😄 |
This would be a fantastic feature |
Hi, any progress on this PR? I temporarily fixed the bug on my boilerplate using @supasate 's connected-react-router, (if you want to see the working example) and I'm glad to see its gonna merge with the official react-router-redux, once this PR is done I'll be happy to switch back to use the react-router-redux again. Thanks so much for you all build this awesome tool 😆 |
Like others here, I too would love to see react-router-redux work with time travelling! |
This would be pretty awesome! |
I would too, but I've had zero motivation to work on this because it's always going to be quirky and lead to a lot more pain than actually helping DX. If someone wants to build on this PR, feel free to submit a new one that uses this code as a basis (or carve your own path). |
…nnected-react-router revert this commit when remix-run/react-router#4717 is merged
It would be amazing to have this. Is it tracked by an issue? I couldn't see one :( |
fb3a586
to
f9481bb
Compare
Just adding my 2 cents as I was hitting this + another bug while I was trying to quickly replay a stored state exported from devtools at startup (did properly connect the location prop to prevent update blocking but it would not work): import state from './state.json';
class App extends PureComponent {
componentDidMount() {
if (state.payload) {
const actions = JSON.parse(state.payload);
actions.forEach(action => store.dispatch(action));
}
}
render() {
return (
<Provider store={store}>
<AppRouter />
</Provider>
);
}
} I can confirm that using connected-react-router did both fix the time-traveling issue and my restore state issue. As a side note, @timdorr I know you must be really busy but your feedback sounds a bit foggy for me and not really actionable, I did not really understand what issues you had with this PR and what would make you accept a new PR on this. Anyway, thanks for the hard work! |
8f33936
to
1fb8696
Compare
Closing this out since react-router-redux is deprecated. Use connected-react-router instead! |
Hi @timdorr,
This is my first attempt to make it work with time travelling.
I make a repo to demonstrate that it starts working now.
However, there are two known problems.
Internal browser stack is modified when time travelling. It should be later fixed with Hook an external listener zalmoxisus/redux-devtools-instrument#15, so, I ignore it for now.
reset
test case is fail. This is crucial and needs to discuss.This problem is caused by the
reset
action will reset the store to its initial state which its location state isnull
and cannot be pushed to the history object.In connected-react-router, we solved this issue by providing the initial history to be the initial location state in the store like the following:
This pattern (higher order reducer) has some advantages.
null
(and the devtools'sreset()
will bring the store to match with the first URL request).LOCATION_CHANGE
action at the beginning.routerReducer
to the root reducer. It will be done automatically with the keyrouter
.I also make a PR to
connected-react-router
to check that it works with same test case.So, if you think this pattern is the right way to go, I will try refactoring the reducer.