reactjs/react-router-redux

Why there is no action creator for LOCATION_CHANGE?

01e9 opened this issue · 2 comments

01e9 commented

I expected this to work (I need it in tests)

const state = routerReducer(undefined, push("/test"))

but after investigating the source code it turns out I have to do

const state = routerReducer(undefined, {
      type: LOCATION_CHANGE,
      payload: {
        path: '/bar',
        action: 'PUSH'
      }
})

That action is generated by the history instance after the navigation has occurred. If you need to test that, hook up a memory history, sync it, and push to it instead.

01e9 commented

It's very confusing that the route is reacting only to history, skipping store state. Now the location stored in state is just a read-only copy of history current location. history is the one that affects the Route render process not the store state.

The workflow now is

history.push()
└ ConnectedRouter[history] 
  └ Route(history.path) # render
    └ routerMiddleware
      └ routerReducer
        └ store

instead of

history.push()
└ ConnectedRouter[history]
  └ routerMiddleware
    └ routerReducer
      └ store
        └ Route(state.router.path) # render

As I expect in a redux app the store to be a central place where the current location is stored. But for routing there is a second place history where the current location is stored and I have to be aware of this case.

Now in my tests I am required besides <Provider store={store}>, instead of <MemoryRouter> to do <ConnectedRouter history={history}> because state = {router: {location: "/test"}} has no effect, I need to do history.push("/test") in order for the right Route to render.

But for this to work you will have to create a Route that is connected to store, not the one from 'react-router-dom' that is connected to history.

Does this make any sense or I am missing something?

Can you provide an example of test that uses createMockStore?