In [email protected]
, I was looking for a way to compose things for a <Route>
's onEnter
hook. For instance:
I did it using the "middleware" pattern described below. My questions are:
react-router
(would require an API change)? or should it just be a "recipe" in the examples directory?// Used to compose Route `onEnter` and `onLeave` hooks.
// Middlewares look like:
//
// function middleware(next) {
// return function handler(nextState, transition) {
// if (condition) {
// transition.to('/some/path');
// return;
// }
// return next(nextState, transition);
// }
// }
function applyMiddleware(...middlewares) {
// Middleware handlers are all side-effect,
// so if we reach the last we don't need to do anything
var finish = _.noop;
// Middlewares will be called from left to right
// until one of them doesn't call `next(nextState, transition)`
var handler = _.compose(...middlewares)(finish);
return function(nextState, transition) {
return handler(nextState, transition);
};
}
// Auth middleware
function requireAuth(next) {
return function(nextState, transition) {
if (!auth.isLoggedIn()) {
transition.to('/login', null, {redirect: nextState.location});
return;
}
next(nextState, transition);
};
}
// Default search query middleware
function ensureQuery(next) {
function(nextState, transition) {
if (_.isEmpty(nextState.location.query)) {
transition.to('/search', defaultQuery);
return;
}
next(nextState, transition);
};
}
var router = (
<Router history={history}>
<Route component={App}>
<Route path="login" component={Login}/>
<Route path="account" component={Account} onEnter={applyMiddleware(requireAuth)}/>
<Route path="search" component={Search} onEnter={applyMiddleware(requireAuth, ensureQuery)}/>
<Redirect from="/" to="search" />
</Route>
</Router>
);
+1 was looking for the same thing
seems cool, I'll leave open for later consideration
You can actually do "middleware" with route hierarchy:
<Router>
<Route onEnter={requireAuth}>
<Route onEnter={addDefaultQuery>
<Route path="/" component={App}/>
<Route>
</Route>
</Router>
Or build a middleware layer yourself, with whatever API you'd like and pass it into the top, a lot like redux reducers:
var middleware = compose(requireAuth, addDefaultQuery, ...etc);
<Router>
<Route onEnter={middleware}>
<Route path="/" component={App}/>
</Route>
</Router>
Most helpful comment
You can actually do "middleware" with route hierarchy:
Or build a middleware layer yourself, with whatever API you'd like and pass it into the top, a lot like redux reducers: