React redux不会改变路线

时间:2018-06-08 07:19:16

标签: reactjs redux react-router react-router-v4

更新此问题以使用connected-react-router代替react-router-redux,因为它与react-router v4不兼容。

在调度操作时,我似乎无法使我的路由工作。我怀疑是因为我正在使用未正确配置的传奇。

我有一个传奇:

import { call } from 'redux-saga/effects'
import { push } from 'connected-react-router'

//...

yield call(push, '/dashboard')

尽管webdev工具中的redux日志显示已成功调度该操作,但push函数不会将浏览器重定向到指定的路径。

顶级index.js文件如下所示:

import createSagaMiddleware from 'redux-saga'
import rootSaga from './redux/sagas'
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import logger from 'redux-logger'
import App from './App'
import registerServiceWorker from './registerServiceWorker'
import rootReducer from './redux/modules'
import { applyMiddleware, compose, createStore } from 'redux'
import { createBrowserHistory } from 'history'
import { routerMiddleware, connectRouter } from 'connected-react-router'

const history = createBrowserHistory()
const sagaMiddleware = createSagaMiddleware()
const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const store = createStore(
  connectRouter(history)(rootReducer),
  composeEnhancer(
    applyMiddleware(
      sagaMiddleware,
      routerMiddleware(history),
      logger
    )
  )
)

sagaMiddleware.run(rootSaga)

const render = () => {
  ReactDOM.render(
    <Provider store={store}>
      <App history={history} />
    </Provider>,
    document.getElementById('root')
  )
}

render()

registerServiceWorker()

包含根组件的App.js文件包含:

import { ConnectedRouter } from 'connected-react-router'
import { Route, Switch, Redirect } from 'react-router-dom'

const App = ({ history }) => {
  return (
    <ConnectedRouter history={history}>
      <Switch>
        { routes }
      </Switch>
    </ConnectedRouter>
  )
}

export default App

此设置中缺少什么才能使其正常工作?

依赖版本:

"react-redux": "^5.0.7",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"connected-react-router": "^4.3.0"

4 个答案:

答案 0 :(得分:2)

您需要连接router's middleware,例如:

import { browserHistory } from 'react-router'
import { routerMiddleware } from 'react-router-redux'

const sagaMw = createSagaMiddleware()
const routerMw = routerMiddleware(browserHistory)
const middleware = applyMiddleware(sagaMw, routerMw, logger)

答案 1 :(得分:2)

push connected-react-router方法(这是一个不纯的函数)不同,push&#39; s redux-saga 动作创建者 及其结果( 动作 )必须发送以触发导航。
要在put中执行此操作,您必须使用call,而不是call

put创建 调用效果 屈服时,它只是用给定的参数执行给定的函数并返回一个结果。通过将我们与函数的直接执行分离,它非常适合(但不限于)不纯的函数调用(例如网络请求)。

dispatch创建 调度效果 屈服时,它会调度传递给动作对象。因此,仅将代码与yield put(push('/dashboard')) 的直接调用解耦,而不是动作创建者(应该是纯粹的设计)。

因此,在您的情况下,解决方案将如下所示:

react-router-redux

P.S:同样适用于push&#39; {{1}}

答案 2 :(得分:0)

  

Sagas实现为生成函数,生成对象   redux-saga中间件

所以你的Saga应该导出一个 Generator 函数:

import { call } from 'redux-saga/effects'
import { push } from 'connected-react-router'

//...

export function* rootSaga() {
    return yield call(push, '/dashboard')
}

rootSaga应注册sagaMiddleware

import { rootSaga } from './redux/sagas';
...
sagaMiddleware.run(rootSaga)
...

参考:https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html

答案 3 :(得分:0)

对我来说似乎有用的是使用withRoter(不知道这是否正确):

export default withRouter(compose(withConnect)(App)); //wrapped in withRouter

export default compose(
  withRouter,
  withConnect,
)(App);

在redux-saga中:

yield put(push('/newpage'));

我使用react-boilerplate https://github.com/react-boilerplate/react-boilerplate。 我不知道它是否正确,但是通过这种方式,路由在url中发生了变化,我进入了新的路由。如果我不使用withRouter,则路由会在url中发生变化,并且什么也没有发生... 我在这里https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.md

找到了解决方案

想对此发表意见。 https://github.com/react-boilerplate/react-boilerplate的人们也许吗?