Реквизиты 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'))

Однако реквизиты для match location остаются прежними значениями или какими бы ни были первые страницы.

Что случилось?


person ilovett    schedule 17.08.2018    source источник


Ответы (2)


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

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

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

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

--

Обновлять:

Возможно, вам просто нужно обернуть ваш компонент с помощью

<Route render={ (routerProps) => <YourConnectedComponent { ...routerProps } />
person ilovett    schedule 17.08.2018
comment
СПАСИБО. сделал мой день. - person rvandoni; 19.11.2018
comment
Не могли бы вы опубликовать пример кода, как в вашем вопросе? - person Imran Ahmad; 30.06.2019

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

У меня была аналогичная проблема, когда я ввел 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>

Когда я пришел в проект, он работал нормально, но затем я решил провести рефакторинг компонента макета и подключил его к хранилищу, что привело к тому, что Component2 перестал получать правильные значения в 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>
person Ademar    schedule 20.01.2021