动作重做后反应路由器重定向


72

我正在使用react-redux和标准react-routing。确定动作后,我需要重定向。

例如:我已经注册了几个步骤。并采取以下措施:

function registerStep1Success(object) {
    return {
        type: REGISTER_STEP1_SUCCESS,
        status: object.status
   };
}

我希望他重定向到带有registrationStep2的页面。怎么做?

ps在历史记录浏览器中从未使用过“ / registrationStep2”。仅在成功注册结果步骤1页面之后,才会显示此页面。


1
反应路由器-DOM V4解决方案可以在这里找到:stackoverflow.com/questions/42701129/...
瑞安奥唐奈

Answers:


63

使用React Router 2+,无论您在何处调度操作,都可以调用browserHistory.push()(或者hashHistory.push()如果使用的话):

import { browserHistory } from 'react-router'

// ...
this.props.dispatch(registerStep1Success())
browserHistory.push('/registrationStep2')

您也可以从异步操作创建者处执行此操作。


1
将来使用beta版的redux-router有什么好处?
ximet

6
如果您想让Redux DevTools重播路由转换,则需要在github.com/acdlite/redux-routergithub.com/reactjs/react-router-redux之间进行选择。在这种情况下,我会推荐github.com/reactjs/react-router-redux,因为它更稳定,更简单。
丹·阿布拉莫夫

2
这个解决方案仍然可用吗?我似乎无法正常工作...使用后URL更新,browserHistory.push()但视图未更新。
vasekhlav

1
没关系,browserHistory.push()尽管路由器已使用,但我正在使用它hashHistoryhashHistory.push()奇迹般有效。
vasekhlav

14
这对于React Router 4+仍然适用吗?还是现在有更好的方法来做到这一点?
Joerg '18

24

您是否签出了react-router-redux?这个库可以使react-router与redux同步。

这是文档中的示例,说明如何通过react-router-redux的push操作实现重定向。

import { routerMiddleware, push } from 'react-router-redux'

// Apply the middleware to the store
const middleware = routerMiddleware(browserHistory)
const store = createStore(
  reducers,
  applyMiddleware(middleware)
)

// Dispatch from anywhere like normal.
store.dispatch(push('/foo'))

我知道路由。但是,我想知道是否可以使用标准的反应路线
ximet

19
以及如何在Action(使用react-router-redux)之后在另一页面上重定向?
ximet

能进入减速机内的店铺吗?
安特

6
现在已弃用react-router-redux。请改一下github.com/supasate/connected-react-router
Uj Corb,

7

路由器版本4+的最简单解决方案:我们使用“ react-router-dom”:“ 4.3.1” 不适用于版本5+

从初始化位置导出浏览器历史记录,并使用browserHistory.push('/ pathToRedirect'):

必须安装软件包历史记录(例如:“ history”:“ 4.7.2”):

npm install --save history

在我的项目中,我在index.js中初始化浏览器历史记录:

import { createBrowserHistory } from 'history';

export const browserHistory = createBrowserHistory();

重定向操作:

export const actionName = () => (dispatch) => {
    axios
            .post('URL', {body})
            .then(response => {
                // Process success code
                  dispatch(
                    {
                      type: ACTION_TYPE_NAME,
                      payload: payload
                    }
                  );
                }
            })
            .then(() => {
                browserHistory.push('/pathToRedirect')
            })
            .catch(err => {
                // Process error code
                    }
                );
            });
};

它确实会更改url,但不会影响“反应路由器”。如果您正在使用此模块-我建议您寻找其他解决方案。
YanivGK

该解决方案仍然可以完美运行,但还有很多其他解决方案。
Jackkobec

对于此解决方案,请使用“ react-router-dom”:“ 4+”。我们使用“ react-router-dom”:“ 4.3.1”
Jackkobec

我只是再次尝试,仍然无法正常工作。我实际上使用"react-router-dom": "5.2.0",即使url浏览器所做的更改无法浏览到所需页面。我想我可能会提出一个不同的问题,这似乎很奇怪。
YanivGK

1
此解决方案不适用于Router v5。对于此解决方案,请使用“ react-router-dom”:“ 4+”。我们使用“ react-router-dom”:“ 4.3.1
Jackkobec

4

要以Eni Arinde先前的答案为基础(我不敢发表评论),以下是store.dispatch异步操作后如何使用该方法的方法:

export function myAction(data) {
    return (dispatch) => {
        dispatch({
            type: ACTION_TYPE,
            data,
        }).then((response) => {
            dispatch(push('/my_url'));
        });
    };
}

诀窍是在操作文件中而不是在reducer中执行此操作,因为reducer应该没有副作用。


1
即使该解决方案有效,也不应该让所有IMO都知道动作。您应该能够在没有任何路由的情况下调度动作。
wintercounter

这是解决问题的正确方法吗?我们是否应该将历史对象从组件传递到动作创建者进行路由?
Jitin Maherchandani


2
您如何链接调度电话?dispatch()。then(()=> dispatch)吗?它似乎不起作用。“那么就不是一个功能”
Nour

3

您可以在“ react-router-dom”中使用{ withRouter }

下面的示例演示了要推送的调度

export const registerUser = (userData, history) => {
  return dispatch => {
    axios
    .post('/api/users/register', userData)
    .then(response => history.push('/login'))
    .catch(err => dispatch(getErrors(err.response.data)));
  }
}

历史参数在组件中分配为动作创建者的第二个参数(在本例中为“ registerUser”)


您能否分享相关的imports和其余的代码?
YanivGK

0

这是路由应用程序的工作副本

    import {history, config} from '../../utils'
        import React, { Component } from 'react'
        import { Provider } from 'react-redux'
        import { createStore, applyMiddleware } from 'redux'
        import Login from './components/Login/Login';
        import Home from './components/Home/Home';
        import reducers from './reducers'
        import thunk from 'redux-thunk'

        import {Router, Route} from 'react-router-dom'

        import { history } from './utils';

        const store = createStore(reducers, applyMiddleware(thunk))



        export default class App extends Component {
          constructor(props) {
            super(props);

            history.listen((location, action) => {
              // clear alert on location change
              //dispatch(alertActions.clear());
            });
          }
          render() {
            return (
              <Provider store={store}>
                <Router history={history}>
                  <div>
                    <Route exact path="/" component={Home} />
                    <Route path="/login" component={Login} />
                  </div>
                </Router>
              </Provider>
            );
          }
        }

export const config = {
    apiUrl: 'http://localhost:61439/api'
};
import { createBrowserHistory } from 'history';

    export const history = createBrowserHistory();
//index.js
export * from './config';
export * from './history';
export * from './Base64';
export * from './authHeader';

import { SHOW_LOADER, AUTH_LOGIN, AUTH_FAIL, ERROR, AuthConstants } from './action_types'

import Base64 from "../utils/Base64";

import axios from 'axios';
import {history, config, authHeader} from '../utils'
import axiosWithSecurityTokens from '../utils/setAuthToken'


export function SingIn(username, password){


    return async (dispatch) => {
      if(username == "gmail"){
        onSuccess({username:"Gmail"}, dispatch);
      }else{
      dispatch({type:SHOW_LOADER, payload:true})
        let auth = {
            headers: {
              Authorization: 'Bearer ' + Base64.btoa(username + ":" + password)
            }
          }
        const result = await axios.post(config.apiUrl + "/Auth/Authenticate", {}, auth);
        localStorage.setItem('user', result.data)
        onSuccess(result.data, dispatch);
    }
  }

}

export function GetUsers(){
  return async (dispatch) => {
var access_token = localStorage.getItem('userToken');
    axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}` 

    var auth = {
      headers: authHeader()
    }
    debugger
      const result = await axios.get(config.apiUrl + "/Values", auth);
      onSuccess(result, dispatch);
      dispatch({type:AuthConstants.GETALL_REQUEST, payload:result.data})
  }
}



const onSuccess = (data, dispatch) => {

  const {username} = data;
  //console.log(response);
  if(username){
    dispatch({type:AuthConstants.LOGIN_SUCCESS, payload: {Username:username }});
    history.push('/');
    // Actions.DashboardPage();
  }else{
    dispatch({ type: AUTH_FAIL, payload: "Kullanici bilgileri bulunamadi" });
  }
  dispatch({ type: SHOW_LOADER, payload: false });
}
const onError = (err, dispatch) => {
  dispatch({ type: ERROR, payload: err.response.data });
  dispatch({ type: SHOW_LOADER, payload: false });
}

export const SingInWithGmail = () => {
  return { type :AuthConstants.LOGIN_SUCCESS}
}

export const SignOutGmail = () => {
  return { type :AuthConstants.LOGOUT}
}

0
signup = e => {
  e.preventDefault();
  const { username, fullname, email, password } = e.target.elements,
    { dispatch, history } = this.props,
    payload = {
      username: username.value,
      //...<payload> details here
    };
  dispatch(userSignup(payload, history));
  // then in the actions use history.push('/<route>') after actions or promises resolved.
};

render() {
  return (
    <SignupForm onSubmit={this.signup} />
    //... more <jsx/>
  )
}

0

使用钩子的更新答案;适用于路由器v5用户。

正在努力react-router-dom:5.1.2

无需安装外部软件包。

import { useHistory } from "react-router-dom";

function HomeButton() {
  let history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}

您可以history像以前一样使用。

更多详细信息和API-阅读手册

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.