代码之家  ›  专栏  ›  技术社区  ›  Rachomir

React Router v4+Redux Saga导航

  •  10
  • Rachomir  · 技术社区  · 7 年前

    我正在尝试在成功的身份验证过程(登录/注册后)后移动用户,但我在internet上找到的每个解决方案(stackoverflow/github问题/介质等)似乎都不起作用!

    请在下面找到我的代码。

    import { call, put, takeLatest } from 'redux-saga/effects'
    import { push } from 'react-router-redux'
    
    import { USER_LOGIN_SUCCEEDED, USER_LOGIN_FAILED, USER_LOGIN_REQUESTED } from '../actions/types'
    
    import { login } from '../api'
    
    function * loginUser (action) {
      try {
        const token = yield call(login, action.payload.email, action.payload.password)
        yield put({type: USER_LOGIN_SUCCEEDED, token: token})
        yield put(push('/dashboard'))
      } catch (error) {
        yield put({type: USER_LOGIN_FAILED, error: error.message})
      }
    }
    
    function * loginSaga () {
      yield takeLatest(USER_LOGIN_REQUESTED, loginUser)
    }
    
    export default loginSaga
    

    不确定是否有必要,但我也会粘贴我的路由器代码

        import React from 'react'
    import { Route } from 'react-router-dom'
    import { connect } from 'react-redux'
    import PropTypes from 'prop-types'
    
    import ForgotPasswordForm from './components/home-page/ForgotPasswordForm'
    import LoginForm from './components/home-page/LoginForm'
    import RegisterForm from './components/home-page/RegisterForm'
    import ResetPasswordForm from './components/home-page/ResetPasswordForm'
    
    import Dashboard from './containers/Dashboard'
    import HomePage from './containers/HomePage'
    
    import PrivateRoute from './helpers/privateRoute'
    
    import './index.scss'
    
    class App extends React.Component {
      componentDidMount () {
        const token = window.localStorage.token
        if (token) {
          this.props.dispatch({type: 'USER_LOGIN_SUCCEEDED', token: token})
        }
      }
    
      render () {
        return (
            <div>
              <Route exact path='/' component={HomePage} />
              <Route path='/login' component={LoginForm} />
              <Route path='/register' component={RegisterForm} />
              <Route path='/forgot-password' component={ForgotPasswordForm} />
              <Route path='/reset-password/:resetPasswordToken' component={ResetPasswordForm} />
              <PrivateRoute path='/dashboard' component={Dashboard} />
            </div>
        )
      }
    }
    
    App.propTypes = {
      dispatch: PropTypes.func.isRequired
    }
    
    export default connect()(App)
    

    最后是索引。js代码

    import React from 'react'
    import { render } from 'react-dom'
    import { Provider } from 'react-redux'
    import { createStore, applyMiddleware, compose } from 'redux'
    import createSagaMiddleware from 'redux-saga'
    import { ConnectedRouter, routerMiddleware } from 'react-router-redux'
    import createHistory from 'history/createBrowserHistory'
    
    import App from './App.js'
    
    import rootReducer from './reducers/rootReducer'
    import setAuthorizationToken from './helpers/setAuthorizationToken'
    import loginSaga from './sagas/loginSaga'
    import registerSaga from './sagas/registerSaga'
    
    const sagaMiddleware = createSagaMiddleware()
    
    const history = createHistory()
    
    const reduxRouterMiddleware = routerMiddleware(history)
    
    const store = createStore(
      rootReducer,
      compose(
        applyMiddleware(sagaMiddleware, reduxRouterMiddleware),
        window.devToolsExtension ? window.devToolsExtension() : f => f
      )
    )
    
    sagaMiddleware.run(registerSaga)
    sagaMiddleware.run(loginSaga)
    
    if (window.localStorage.token) {
      setAuthorizationToken(window.localStorage.token)
    }
    
    render(
      <Provider store={store}>
        <ConnectedRouter history={history}>
          <App />
        </ConnectedRouter>
      </Provider>,
      document.getElementById('app')
    )
    

    知道为什么它不起作用吗?我还尝试在saga文件中导入browserHistory,并使用 yield browserHistory.push('/dashboard')

    我们将非常感谢您的帮助。

    小更新-我现在收到此错误 enter image description here

    3 回复  |  直到 7 年前
        1
  •  5
  •   欧阳维杰    7 年前

    您可以从中使用createHistory history 包裹在传奇中,将其传递给react路由器并访问它。

    /** history.js ****/
    import {createBrowserHistory} from 'history'
    
    export default createBrowserHistory({your_config_here})
    
    /** saga.js ***/
    import {... call} from 'redux-saga/effects'
    import history from './history'
    export default function* your_root_saga(){
      ...access history here or in your sub sagas...
      yield call([history, history.push], 'your_object_path')
    }
    
    
    /** index.js ****/
    import history from './history'
    import {Router, ...} from 'react-router-dom'
    import your_root_saga from './sagas'
    import {createSagaMiddleware} from 'redux-saga'
    
    const sagaMiddleware = createSagaMiddleware()
    ...config_your_store_here...
    sagaMiddleware.run(your_root_saga)
    
    
    render( <Router history = {history}> ... </Router>
    , document.getElementById('elementId'))
    
        2
  •  3
  •   Alex    7 年前

    您没有完全设置react router redux( https://github.com/ReactTraining/react-router/tree/master/packages/react-router-redux )

    你需要

    • 已连接外部
    • 路由器减速器
    • 路由器中间件

    否则,redux不知道如何处理推送操作——没有任何reducer或中间件知道该操作,所以他们会忽略它。

        3
  •  0
  •   JizoSaves    7 年前

    看起来您忘记添加routerReducer-请尝试以下操作:

    import React from 'react'
    import { render } from 'react-dom'
    import { Provider } from 'react-redux'
    import { createStore, applyMiddleware, compose,
      combineReducers  // need this to add the routerReducer
    } from 'redux'
    import createSagaMiddleware from 'redux-saga'
    import {
      ConnectedRouter,
      routerMiddleware,
      routerReducer // you need the router reducer
    } from 'react-router-redux'
    import createHistory from 'history/createBrowserHistory'
    
    import App from './App.js'
    
    import rootReducer from './reducers/rootReducer'
    import setAuthorizationToken from './helpers/setAuthorizationToken'
    import loginSaga from './sagas/loginSaga'
    import registerSaga from './sagas/registerSaga'
    
    const sagaMiddleware = createSagaMiddleware()
    
    const history = createHistory()
    
    const reduxRouterMiddleware = routerMiddleware(history)
    
    const store = createStore(
      combineReducers({...rootReducer, router: routerReducer}),
      compose(
        applyMiddleware(sagaMiddleware, reduxRouterMiddleware),
        window.devToolsExtension ? window.devToolsExtension() : f => f
      )
    )
    
    sagaMiddleware.run(registerSaga)
    sagaMiddleware.run(loginSaga)
    
    if (window.localStorage.token) {
      setAuthorizationToken(window.localStorage.token)  
    }
    
    render(
      <Provider store={store}>
        <ConnectedRouter history={history}>
          <App />
        </ConnectedRouter>
      </Provider>,
      document.getElementById('app')
    )