Реагировать на маршрутизатор после действия
Я использую реакцию-редукцию и стандартную реакцию-маршрутизацию. Мне нужно перенаправить после определенного действия.
Например: у меня есть регистрация на несколько шагов. И после действия:
function registerStep1Success(object) {
return {
type: REGISTER_STEP1_SUCCESS,
status: object.status
};
}
Я хочу, чтобы он перенаправлялся на страницу с регистрациейStep2. Как это сделать?
p.s. В браузере истории '/registrationStep2' никогда не было. Эта страница появляется только после успешной регистрации результатов на странице Stepp.
Ответы
Ответ 1
С React Router 2+, где бы вы ни отправили действие, вы можете вызвать browserHistory.push()
(или hashHistory.push()
, если это то, что вы используете):
import { browserHistory } from 'react-router'
// ...
this.props.dispatch(registerStep1Success())
browserHistory.push('/registrationStep2')
Вы можете сделать это и от создателей асинхронного действия, если это то, что вы используете.
Ответ 2
Вы проверили react-router-redux? Эта библиотека позволяет синхронизировать реактивный маршрутизатор с сокращением.
Вот пример из документации о том, как вы можете реализовать перенаправление с помощью push-действия от response-router-redux.
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'))
Ответ 3
Чтобы основываться на предыдущем ответе Eni Arinde (у меня нет репутации для комментариев), вот как использовать метод store.dispatch
после асинхронного действия:
export function myAction(data) {
return (dispatch) => {
dispatch({
type: ACTION_TYPE,
data,
}).then((response) => {
dispatch(push('/my_url'));
});
};
}
Хитрость заключается в том, чтобы делать это в файлах действий, а не в редукторах, поскольку редукторы не должны иметь побочных эффектов.
Ответ 4
Самое простое решение для версии маршрутизатора 4+:
экспортируйте историю браузера из того места, где она была инициализирована, и используйте 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
}
);
});
};
Ответ 5
Вы можете использовать { withRouter } из'act -router-dom '
Пример ниже демонстрирует отправку, чтобы нажать
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')
Ответ 6
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/>
)
}
Ответ 7
Вот рабочая копия приложения маршрутизации
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}
}