Я в своем проекте сделал надстройку над react-router, главным образом потому, что там коряво реализована интеграция с redux. У react-redux-router из коробки диспатч экшена происходит после того, как произошел собственно роутинг, т.е. налицо костыль; у меня же смена роута является следствием экшена, что мне и было необходимо достичь.
Поэтому ответ - да, можно, но без роутера все равно не обойтись. Если вас не устраивает нативный роутер, создайте свой собственный, где слушаете history, и там можете управлять флоу как вам удобно. А дальше уже в обработчиках ваших экшенов будете производить все проверки и в редьюсере менять стейт.
Например, код моего роутера:
spoilerimport React from 'react';
import createHistory from 'history/createHashHistory';
import { Router } from 'react-router-dom';
import * as routerActions from './Actions/RouterActions';
class HashRouter extends React.Component {
constructor(props, context) {
super(props, context);
this.history = createHistory();
this.history.listen(this.onHistoryChange.bind(this));
this.store = this.props.store || this.context.store;
}
/**
* Just initialize start route.
*/
componentDidMount() {
const { location } = this.history;
const User = new UserEntity;
const accessLevel = User.getRole();
const routes = RoutesRepository.getRoutesBy(accessLevel);
const match = RoutesRepository.getMatch(location, routes);
this.store.dispatch(
routerActions.routeChange(match)
)
}
render() {
return <Router history={this.history}>
{this.props.children}
</Router>;
}
/**
* When user change browser history,
* dispatch actions for change routes.
*
* @param location Object
* @param action String
* @return void
*/
onHistoryChange(location, action) {
if(!this.store) {
return null;
}
const User = new UserEntity;
const accessLevel = User.getRole();
const routes = RoutesRepository.getRoutesBy(accessLevel);
const match = RoutesRepository.getMatch(location, routes);
this.store.dispatch(routerActions.routeChange(match));
}
}