React Router props `location` / `match` not updating with `ConnectedRouter`
Asked Answered
S

2

5

I've got my app setup as in the docs:

Step 1

...
import { createBrowserHistory } from 'history'
import { applyMiddleware, compose, createStore } from 'redux'
import { connectRouter, routerMiddleware } from 'connected-react-router'
...
const history = createBrowserHistory()

const store = createStore(
  connectRouter(history)(rootReducer), // new root reducer with router state
  initialState,
  compose(
    applyMiddleware(
      routerMiddleware(history), // for dispatching history actions
      // ... other middlewares ...
    ),
  ),
)

Step 2

...
import { Provider } from 'react-redux'
import { Route, Switch } from 'react-router' // react-router v4
import { ConnectedRouter } from 'connected-react-router'
...
ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}> { /* place ConnectedRouter under Provider */ }
      <div> { /* your usual react-router v4 routing */ }
        <Switch>
          <Route exact path="/" render={() => (<div>Match</div>)} />
          <Route render={() => (<div>Miss</div>)} />
        </Switch>
      </div>
    </ConnectedRouter>
  </Provider>,
  document.getElementById('react-root')
)

I click on a Link or even dispatch(push('/new-url/withparam'))

However the props for match location are remaining the previous values or whatever the first page was.

What is happening?

Smiley answered 17/8, 2018 at 22:52 Comment(0)
S
12

This one has bitten me many times.

Your Switch and Route etc. MUST NOT BE INSIDE A CONNECTED COMPONENT!

If the component is connected, the props for match, location, etc. don't seem to get updated and propagate down to your routes.

This means don't connect your top level App or Root, or any other nested containers between the ConnectedRouter and Route

--

Update:

You may just need to wrap your component with

<Route render={ (routerProps) => <YourConnectedComponent { ...routerProps } />
Smiley answered 17/8, 2018 at 22:52 Comment(2)
THANKS. made my day.Binal
Can you please post the example code as in your question?Sedative
A
0

I decided to add example to here as I feel it is valuable input - even tho, it's already answered.

I had similar problem, when I pushed url into router history, it changed URL but it didn't navigate properly on the component I wanted. I googled and searched for answer for hours, until I found this thread which finally helped me to find out what I made wrong. So all credits to @ilovett.

So here is an example, if someone will need it for better understanding:

I had code similar to this:

export const routes =
    <Layout>
        <Switch>
            <Route exact path='/' component={ Component1 } />
            <Route path='/parameter1/:parameterValue' component={ Component2 } />
        </Switch>
    </Layout>;

<Provider store={ store }>
    <ConnectedRouter history={ history } children={ routes } />
</Provider>

It was working fine when I came to a project, but then I decided to refactor Layout component and I connected it to the store which caused that Component2 stopped receiving correct values in the ownProps.match.params.parameter1 and because of that it rendered component completely wrong.

So only thing what you need to do is move Layout outside of ConnectedRouter. Nothing between ConnectedRouter and Route can be connected to the store.

Working example is this then:

export const routes =
        <Switch>
            <Route exact path='/' component={ Component1 } />
            <Route path='/parameter1/:parameterValue' component={ Component2 } />
        </Switch>;

<Provider store={ store }>
    <Layout>
        <ConnectedRouter history={ history } children={ routes } />
    </Layout>
</Provider>
Angola answered 20/1, 2021 at 18:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.