React Router поддерживает `location` / `match`, который не обновляется с помощью `ConnectedRouter`

У меня есть настройки моего приложения, как в документации:

Шаг 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 ...
    ),
  ),
)

Шаг 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')
)

Я нажимаю на Link или даже dispatch(push('/new-url/withparam'))

Однако реквизит для matchlocation остаются предыдущие значения или любой другой первой страницы.

Что происходит?

2 ответа

Этот укусил меня много раз.

Ваш Switch а также Route и т.д. НЕ ДОЛЖНЫ БЫТЬ ВНУТРИ ПОДКЛЮЧЕННОГО КОМПОНЕНТА!

Если компонент подключен, реквизит для match, location и т. д. не обновляются и не распространяются на ваши маршруты.

Это означает, что не подключайте ваш верхний уровень App или же Root или любые другие вложенные контейнеры между ConnectedRouter а также Route

Я решил добавить пример сюда, так как считаю, что это ценный вклад - даже несмотря на то, что на него уже ответили.

У меня была аналогичная проблема, когда я вставил URL-адрес в историю маршрутизатора, он изменил URL-адрес, но не смог правильно перейти к нужному мне компоненту. Я гуглил и искал ответ часами, пока не нашел эту ветку, которая, наконец, помогла мне выяснить, что я сделал неправильно. Так что все заслуги @ilovett.

Итак, вот пример, если кому-то понадобится для лучшего понимания:

У меня был код, похожий на этот:

      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>

Когда я пришел к проекту, он работал нормально, но затем я решил реорганизовать компонент макета и подключил его к хранилищу , что привело к тому, что компонент2 перестал получать правильные значения в ownProps.match.params.parameter1 и из-за этого он отображал компонент совершенно неправильно.

Поэтому единственное, что вам нужно сделать, это переместить Layout за пределы ConnectedRouter . Ничто между ConnectedRouter и Route не может быть подключено к хранилищу.

Рабочий пример таков:

      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>
Другие вопросы по тегам