Friday, May 10, 2024
 Popular · Latest · Hot · Upcoming
85
rated 0 times [  90] [ 5]  / answers: 1 / hits: 16551  / 8 Years ago, mon, march 7, 2016, 12:00:00

I would like to make use of react-router's onEnter handler in order to prompt users to authenticate when entering a restricted route.



So far my routes.js file looks something like this:



import React from 'react';
import { Route, IndexRoute } from 'react-router';

export default (
<Route path=/ component={App}>
<IndexRoute component={Landing} />
<Route path=learn component={Learn} />
<Route path=about component={About} />
<Route path=downloads component={Downloads} onEnter={requireAuth} />
</Route>
)


Ideally, I'd like my requireAuth function to be a redux action that has access to the store and current state, that works like this: store.dispatch(requireAuth()).



Unfortunately I don't have access to the store in this file. I don't think I can use really use connect in this case to access the relevant actions that I want. I also can't just import store from the file where the store is created, as this is undefined when the app first loads.


More From » reactjs

 Answers
25

The easiest way to accomplish this is to pass your store to a function that returns your routes (rather than return your routes directly). This way you can access the store in onEnter and other react router methods.



So for your routes:



import React from 'react';
import { Route, IndexRoute } from 'react-router';

export const getRoutes = (store) => (
const authRequired = (nextState, replaceState) => {
// Now you can access the store object here.
const state = store.getState();

if (!state.user.isAuthenticated) {
// Not authenticated, redirect to login.
replaceState({ nextPathname: nextState.location.pathname }, '/login');
}
};

return (
<Route path=/ component={App}>
<IndexRoute component={Landing} />
<Route path=learn component={Learn} />
<Route path=about component={About} />
<Route path=downloads component={Downloads} onEnter={authRequired} />
</Route>
);
)


Then update your main component to call the getRoutes function, passing in the store:



<Provider store={ store }>
<Router history={ history }>
{ getRoutes(store) }
</Router>
</Provider>


As for dispatching an action from requireAuth, you could write your function like this:



const authRequired = (nextState, replaceState, callback) => {
store.dispatch(requireAuth()) // Assume this action returns a promise
.then(() => {
const state = store.getState();

if (!state.user.isAuthenticated) {
// Not authenticated, redirect to login.
replaceState({ nextPathname: nextState.location.pathname }, '/login');
}

// All ok
callback();
});
};


Hope this helps.


[#63025] Friday, March 4, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
paolam

Total Points: 437
Total Questions: 107
Total Answers: 106

Location: Aland Islands
Member since Wed, Nov 17, 2021
3 Years ago
;