Skip to content

Instantly share code, notes, and snippets.

@wtfil
Last active July 7, 2017 16:55
Show Gist options
  • Save wtfil/2ef4faed28442376a6ce to your computer and use it in GitHub Desktop.
Save wtfil/2ef4faed28442376a6ce to your computer and use it in GitHub Desktop.
injection of redux's dispatch in react-router's onEnter hook
/*
* common react, redux staff here
*/
import {Router, createRoutes} from 'react-router';
import createBrowserHistory from 'history/lib/createBrowserHistory';
import rawRoutes from './routes';
import store from './store';
function mixStoreToRoutes(routes) {
return routes && routes.map(route => ({
...route,
childRoutes: mixStoreToRoutes(route.childRoutes),
onEnter: route.onEnter && function (props, replaceState, cb) {
route.onEnter(store.dispatch, props)
.then(() => cb(null))
.catch(cb);
}
}));
}
const routes = mixStoreToRoutes(createRoutes(rawRoutes));
ReactDOM.render(
<Provider store={store}>
<Router
history={createBrowserHistory()}
routes={routes}
/>
</Provider>,
document.querySelector('[data-app]')
);
import {App, Home, Settings, Signup, Login} from './containers';
import {loadSettings} from './actions';
export default (
<Route>
<Route component={App} onEnter={dispatch => dispatch(loadSettings())}>
<Route path="/" component={Home}/>
<Route path="/settings" component={Settings}/>
</Route>
<Route path="/signup" component={Signup} />
<Route path="/login" component={Login} />
</Route>
);
@jawr
Copy link

jawr commented Jul 21, 2016

Hey, nice gist. I have it working thank you very much, but it's throwing an error, which i don't quite understand:

Uncaught TypeError: route.onEnter(...).then is not a function @
route.onEnter(store.dispatch, props).then(function () {

what version are you using that it becomes a promise?

@wtfil
Copy link
Author

wtfil commented Jul 30, 2016

hi @jawr.
the reason you see this error is because this hook relay on promise from onEnter

static onEnter(dispatch, props) {
   return dispatch(someAction());
}

this will work when someAction returns the promise.

the example could be like this

const someAction = () => dispatch => {
    dispatch({type: 'START'});
    return fetch('/api/url')
        .then(res => res.json())
        .then(data => {
              dispatch({type: 'SUCCESS', payload: data});
        })
}

@leventebalogh
Copy link

@wtfil: A really nice one, congrats ;)

Just one small note: I think you accidentally named the mixing function mixDispatch and later you are referring to it as mixStoreToRoutes. So by correcting the typo, it should be something like this IMO:

function mixStoreToRoutes(routes) {
    return routes && routes.map(route => ({
        ...route,
        childRoutes: mixStoreToRoutes(route.childRoutes),
        onEnter: route.onEnter && function (props, replaceState, cb) {
            route.onEnter(store.dispatch, props)
                .then(() => cb(null))
                .catch(cb);
        }
    }));
}

const routes = mixStoreToRoutes(createRoutes(rawRoutes));

@wtfil
Copy link
Author

wtfil commented Aug 19, 2016

@leventebalogh Thx! Did not saw this :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment