react-routerconnected-react-router

Why do <Link> and <Redirect> not trigger updates of state.router in connected-react-router?


After looking around at the various packages to combine redux with react-router, it looked as though connected-react-router was the most popular actively supported choice.

I configured it pretty much exactly as in the docs, with one exception described below.

The problem I am having is that a react-router <Redirect> does redirect, but it does not update state.router.location. Codesandbox MNWE is here. [Edit: I realized just after posting that <Link> is having exactly the same problem, and illustrated it in a slight modification of the original codesandbox. Sorry, would have been clearer if I'd just started there, but I need some sleep!]

In the following example, there are 3 routes. The first matches the root "/". The second matches simple URLs like "/anything" and the default will match things like "/anything/else". <Where> is a little component that shows its text prop and then shows state.router.location.pathname.

 <Switch>
    <Route exact path="/">
        <Where text="Root" />
    </Route>
    <Route exact path="/:thing">
        <Where text="Exact" />
    </Route>
    <Route>
    <Redirect to="/" />
    </Route>
</Switch>

When you arrive, you see "Root: /", as you should. If you add "/anything" in the address bar, you see "Exact: /anything". If you put "/anything/else" in the address bar, the address bar is redirected back to the root, and the <Switch> goes back to match the root, but instead of seeing "Root: /", you see "Root: /anything/else". The logger confirms that although the manually entered URLs trigger state updates, the <Redirect> does not.

Maybe I am wrong to think that it should, but I don't see it documented one way or the other. I imagine that I have made some configuration error?

[The configuration exception that I described is that I do not use combineReducers in my App, I have a single reducer which I call appRootReducer (which is empty in this example). So I wrote a little createRootReducer wrapper. It works well enough that the basic updates to state.router do go through.]

I hope that you can help!


Solution

  • Ack! Searching through closed issues in the Github repo, I see that I had left in my <BrowswerRouter> tags.

    • Wrap your react-router v4/v5 routing with ConnectedRouter and pass the history object as a prop. Remember to delete any usage of BrowserRouter or NativeRouter as leaving this in will cause problems synchronising the state.