-
Notifications
You must be signed in to change notification settings - Fork 642
Split history syncing from action creators #259
Conversation
Getting the easy parts done first.
See reduxjs/redux#1362 Some small modifications and commenting added. Absolutely needs tests!
Not that bad. In fact, it's mostly stuff removed! :)
62b574b
to
1b1f3f6
Compare
Fix Firefox with babel-polyfill.
1b1f3f6
to
4c17b0e
Compare
// Update address bar to reflect store state | ||
isTimeTraveling = true | ||
currentLocation = locationInStore | ||
history.transitionTo(Object.assign({}, |
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.
Let's use spread here so we don't have to worry about polyfilling Object.assign(). Babel still doesn't replace this call automatically does it?
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.
It does. And Travis' version of Firefox (31) is old enough not to have Object.assign built in. So it doesn't really matter either way, but I will probably switch it to a spread. Haven't made it this far down in the file yet 😄
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.
Does it need some special flag?
http://babeljs.io/repl/#?experimental=false&evaluate=false&loose=false&spec=false&code=Object.assign(a%2C%20b)%0A%0A
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.
I think you need this
Thank you very much for getting this moving! I might be able to find some time to contribute in the next week but this is already shaping up nicely 🙃 |
👏 |
Can someone confirm for me that this is just syncing state with rackt/history and the use of react-router is secondary? Any objections to me making a pull request against the synchronicity with the change suggestions above? |
This is correct.
I’m pretty sure any contributions are welcome! |
Was it decided somewhere how defaultState based on current location should be set? This is something that was handled before that seems to be missing now. Having to manually do the following seems a bit inelegant. const history = createHistory()
function initLocation() {
let locationBeforeTransitions
history.listen(loc => locationBeforeTransitions = loc)()
return locationBeforeTransitions
}
const initialState = {
routing: {
locationBeforeTransitions: initLocation()
}
}
const store = createStore(reducer, initialState) Is it the job for a store enhancer? Yes, it is set with an action on invocation of |
Sorry for jumping in without reading the whole thread but I gave 4.0.0-beta.1 a spin along with RR2.0.0. I'm using SSR and accessing e.g
I'm not familiar with the internals but I'd guess the store isn't synced with history state after My (trimmed down) implementation: // server.js
import { createMemoryHistory } from 'react-router'
const { store, syncedHistory } = createStoreWithHistory(createMemoryHistory())
const location = syncedHistory.createLocation(req.url)
match({routes, location}, (error, redirectLocation, routingProps) => {/* ... */}) // client.js
import { browserHistory } from 'react-router'
const { store, syncedHistory } = createStoreWithHistory(browserHistory, window.__data)
ReactDOM.render((
<Provider store={store}>
<Router history={syncedHistory}>
{routes}
</Router>
</Provider>
),
node
) // createStoreWithHistory.js
import { syncHistoryWithStore } from 'react-router-redux'
import { createStore } from 'redux'
function createStoreWithHistory(history, initialState) {
const store = createStore(reducer, initialState)
return {store, syncedHistory: syncHistoryWithStore(history, store)}
} |
@SimenB I can look at IE8 compatibility and implement Redux's solution. Yes, you can keep using the plain history singleton from React Router. The only difference between the two is the @romseguy I haven't done any SSR testing yet. But try this instead: import { createMemoryHistory } from 'react-router'
const { store, syncedHistory } = createStoreWithHistory(createMemoryHistory())
match({routes, location: req.url, history: syncedHistory}, (error, redirectLocation, routingProps) => {/* ... */}) You definitely need to pass the enhanced history into |
Same problem. |
Includes a link to a commit migrating `^3.0.0` to `^4.0.0-beta`. Will update further once it's officially released.
Add example migration from ^3.0.0
[shakacode/react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial). react-router-redux + plus React + Redux + React Router + including **Server Rendering** using [React on Rails](https://github.com/shakacode/react_on_rails/), live at [www.reactrails.com](http://www.reactrails.com/).
Update README.md
added example to readme
@romseguy & @svrcekmichal This was fixed by properly seeding our memory history with the right path: const memoryHistory = createMemoryHistory(req.path) I'll have to check that our SSR docs on react-router are consistent. |
I haven't seen any serious issues come up, so I'm going to merge this into master. I've cut a While there haven't been any changes to the code, I'm going to push an rc1 release shortly. Hopefully, that will signal to more people to give it a try. It works well! That should root out some further bugs and we can make this thing about as good as it can be. |
Split history syncing from action creators
Thank you @timdorr and everyone else, works great now. |
how to use it, is there a doc? |
Big thanks to @gaearon for opening up this can of worms and writing a bunch of code to fix it!
Here's the history (pun intended) of what led to this:
#252 (comment) -> #255 -> #257 -> reduxjs/redux#1362 (PR)
A big giant chunk of this code is copypasta from Dan's work on that Redux PR. I just mashed some buttons until it looked right.
Changes
The provided action creators and middleware are now separate from the history<->state syncing function. For the vast majority of cases, using action creators to trigger navigation is obsoleted by React Router's new history singletons provided in 2.0. Building this functionality in by default and coupling it to our history syncing logic no longer makes sense.
We now sync by enhancing the history instance to listen for navigation events and dispatch those into the store. The enhanced history has its
listen
method overridden to respond to store changes, rather than directly to navigation events. When this history is provided to<Router>
, the router will listen to it and receive these store changes. This means if we time travel with the store, the router will receive those store changes and update based on the location in the store, instead of what the browser says. Normal navigation events (hitting your browser back/forward buttons, telling a history singleton topush
a location) flow through the history's listener like normal, so all the usual stuff works A-OK.TODOs
Fixes #193
Fixes #252