如何使用history.push进行反应

时间:2018-06-18 15:45:28

标签: reactjs react-router react-redux

大家好我创建了一个新的操作来登录用户:

import * as types from './actionTypes';
import sessionApi from '../api/SessionApi';
import auth from '../auth/authenticator';


export function loginSuccess() {
 return {type: types.LOG_IN_SUCCESS}
 }

export function loginUser(credentials) {
 return function(dispatch) {
 return sessionApi.login(credentials).then(response => {

  sessionStorage.setItem('token', response.token);
  dispatch(loginSuccess());
}).catch(error => {

  throw(error);
   });
  };
 }

 export function logOutUser() {
  auth.logOut();
  return {type: types.LOG_OUT}
 }

我为我的auths创建一个会话缩减器,如下所示:

import * as types from '../actions/actionTypes';
import initialState from './initialState';



export default function sessionReducer(state = initialState.session, 
 action) {
  switch(action.type) {
   case types.LOG_IN_SUCCESS:
    // history.push('/restaurant')
    return !!sessionStorage.token
  default:
  return state;
   }
  }

登录成功后,我想使用history.push将我的用户重定向到另一个页面,但我不知道该怎么做?我尝试先导入

import createBrowserHistory from "history/createBrowserHistory"

然后创建一个新的const历史:

export const history = createBrowserHistory({
forceRefresh: true
})

然后

history.push('/restaurant')

但在行动之后,将我从/#home重定向到/ restaurant / #home .... 而不是我正确的组件。 我有2个路由文件,一个用于我的主要视图,如下所示:

const routes = [
 { path: '/', name: 'Home', component: Home },
 { path: '/login', name: 'Login', component: Login },
 { path: '/home', name: 'Landing', component: Landing },
 { path: '/dishes', exact: true, name: 'Detail', component: Dish },
 { path: '/dishes/detail', name: 'DishDetail', component: Detail },
 { path: '/checkout/registration', name: 'Restaurant', component: 
 Registration },
 ];

 export default routes;

和我所有餐厅的观点之一:

const routes = [
{ path: '/restaurant', exact: true, name: 'Restaurant', component: 
RestrauntDashboard },
{ path: '/restaurant/dashboard', name: 'Restaurant Dashboard', 
component: Dashboard },
{ path: '/restaurant/profile', name: 'Restaurant Dashboard', component: 
Profile },
];

export default routes;

这是我的app.js:

class App extends Component {
 render() {
  return (
      <HashRouter>
          <Switch>
              <Route path="/restaurant" name="Restaurant" component= . 
               {RestrauntDashboard} />
              <Route path="/" name="Home" component={Home} />
          </Switch>
      </HashRouter>
   );
 }
}

export default App;

所以最后我想通过使用history.push在用户登录后重定向'/ restaurant /路径,感谢您的帮助

3 个答案:

答案 0 :(得分:0)

由于您使用的是HashRouter,您可以使用Programmatically Navigate using react-router中提及的道具中的history

或者您需要使用createHashHistory而不是createBrowserHistory创建历史记录,并将其传递给通用路由器组件,如

import { Router } from 'react-router-dom';
export const history = createHashHistory();

class App extends Component {
 render() {
  return (
      <Router history={history}>
          <Switch>
              <Route path="/restaurant" name="Restaurant" component= . 
               {RestrauntDashboard} />
              <Route path="/" name="Home" component={Home} />
          </Switch>
      </HashRouter>
   );
 }
}

答案 1 :(得分:0)

除了Shubham的答案之外,处理所有这些重定向的好地方是中间件。一般来说,最好让动作和减速器保持纯净。

您可以在操作对象中添加第三个字段,如下所示

export function loginSuccess() {
  return { 
     type: 'types.LOG_IN_SUCCESS', 
     redirectAfter: '/path/you/wish/to/redirect/after/action'};
  }
}

redirectMiddleware.js

import history from '../history';

const redirectMiddleware = () => next => action => {
  if (action.redirectBefore) {
    history.push(action.redirectBefore);
  }
  const result = next(action);
  if (action.redirectAfter) {
    history.push(action.redirectAfter);
  }
  return result;
};

export default redirectMiddleware;

在商店的config.js中添加中间件

applyMiddleware([redirectMiddleware])

因此,在您的操作中,您可以将redirectBefore作为您要在重定向器操作之前重定向到的路径,或者redirectAfter如果要在将操作传递给reducers之前重定向。

答案 2 :(得分:0)

将登录组件更改为如下所示。

import React from 'react';
import {Redirect} from "react-router-dom";
import {withRouter} from "react-router-dom";
import {compose} from 'redux';
import {connect} from 'react-redux';

const Login = props => {
  return (
    <div>
    /*all login UI */
    //..
    {
      props.isLoggedIn ? 
      <Redirect to={'/restaurant'}/> : null
    }
    </div>
  ) 
};

const mapStateToProps = state => ({
    isLoggedIn: state.session.isLoggedIn //or whatever
});

export default compose(
    withRouter,
    connect(mapStateToProps, mapDispatchToProps)
)(Login);

按如下所示更改您的sessionReducer

export default function sessionReducer(state = initialState.session, action) {
  switch(action.type) {
   case types.LOG_IN_SUCCESS:
    return { ...state, isLoggedIn: true}
  default:
    return state;
  }
}

当用户未登录时isLoggedIn是未定义的,因此它什么也不会呈现,但登录成功后,会为令牌分配一些值,结果<Redirect to='/restaurant'/>会被呈现,并且网站将重定向到/restaurant

如果未定义isLoggedIn出现错误,请将其添加到initialState.js

const initialState = {
  //..
  session: {
    //.. others
    isLoggedIn: false
  }
}

希望这可以解决您的问题。干杯!