[Question] How do we trigger a route change component to render using react-router and redux-saga-router
See original GitHub issueShould the saga router live next to the react-router ?
I don’t see any way to define my previous router in sagas :
export default function createRoutes(store) {
// Create reusable async injectors using getAsyncInjectors factory
const { injectReducer, injectSagas } = getAsyncInjectors(store);
injectSagas(appSagas);
injectSagas([routeSagas]);
return [
{
path: pages.pageLogin.path,
name: pages.pageLogin.name,
onEnter: checkAuth(store),
getComponent(nextState, cb) {
const importModules = Promise.all([
import('containers/LoginPage/reducer'),
import('containers/LoginPage/sagas'),
import('containers/LoginPage'),
]);
const renderRoute = loadModule(cb);
importModules.then(([reducer, saga, component]) => {
// here we load asynchronously one saga and one reducer
injectReducer(STORE_LOGIN_MAIN, reducer.default);
injectSagas(saga.default);
renderRoute(component);
});
},
},
{
path: pages.pageDashboard.path,
name: pages.pageDashboard.name,
onEnter: checkAuth(store),
getComponent(nextState, cb) {
const importModules = Promise.all([
import('containers/DashboardPage/reducers/index'),
import('containers/DashboardPage/sagas/index'),
import('containers/DashboardPage'),
]);
const renderRoute = loadModule(cb);
importModules.then(([reducers, sagas, component]) => {
// here we load asynchronously an array of sagas and reducers
reducers.default.forEach((reducer) => injectReducer(reducer.name, reducer.reducer));
sagas.default.forEach((saga) => injectSagas(saga));
renderRoute(component);
});
importModules.catch(errorLoading);
},
},
{
path: pages.pageTesting.path,
name: pages.pageTesting.name,
onEnter: checkAuth(store),
getComponent(nextState, cb) {
import('containers/TestingPage')
.then(loadModule(cb))
.catch(errorLoading);
},
},
{
path: pages.pageTestingagd.path,
name: pages.pageTestingagd.name,
getComponent(location, cb) {
import('containers/TestingagdPage')
.then(loadModule(cb))
.catch(errorLoading);
},
},
{
path: '*',
name: 'notfound',
onEnter: checkAuth(store),
getComponent(nextState, cb) {
import('containers/NotFoundPage')
.then(loadModule(cb))
.catch(errorLoading);
},
},
];
}
I need to call a services when arriving on /dashboard
, this is my sagas.js
, this work but break my previous route :
import { router, } from 'redux-saga-router';
import { browserHistory } from 'react-router';
import { call, put } from 'redux-saga/effects';
import auth from 'services/auth';
const routes = {
// Method syntax
*'/dashboard'() {
const services = yield call(auth.services);
console.log(services);
// yield put(setUsers(users));
},
//
// // Or long form with function expression
// '/users/:id': function* userSaga({ id }) {
// const user = yield call(fetchUser, id);
// yield put(setCurrentUser(user));
// },
};
function* fetchInitialData(){
}
export default function* mainSaga() {
// const data = yield call(fetchInitialData);
//
// yield put(ready(data));
const start = new Date();
console.log("timeout start", start.toISOString());
console.log("start", new Date().getTime() - start.getTime());
const toto = yield (call(setTimeout, 1000, () => new String('toto')));
console.log("timeout end", new Date().getTime() - start.getTime());
yield* router(browserHistory, routes);
}
I don’t see any code example online, would be nice to get some help here. 😃
Issue Analytics
- State:
- Created 7 years ago
- Comments:7 (4 by maintainers)
Top Results From Across the Web
React/Redux Saga: Need to trigger a route change after user ...
The trick is to include react-router's history into the payload of UPDATE_PAGE. So 1) we wrap a component which triggers this action ...
Read more >Using React Router with Redux - Pluralsight
One of the most common Redux-React Router interactions is to perform a route change after a certain app state is changed. For example,...
Read more >React Router with Redux: Understanding navigation state
Use React Router to declaratively navigate within your React and Redux applications and maintain state across your app's navigation ...
Read more >Running React Router v4, Redux Saga, SSR and Code ...
We are currently migrating a customer project from a Symfony application to a React application with server-side rendering.
Read more >Redux Saga and React Router v4 - YouTube
Learn how to use Redux Saga and React Router v4 together. On your login page, you can make an api request using Redux...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Thanks for the clarification, @kopax!
I cloned the boilerplate repo and created a minimal example that uses redux-saga-router here.
Relevant files:
This example seems to work fine. redux-saga-router responds to the route, faking fetching data, and then dispatching an action to update the fictitious services object. react-router displays the
Dashboard
component. The Dashboard reducer uses aloading
property for theDashboard
component to display a loading message until the services are ready from the saga.Notice, I consolidate the routes by pulling in the
servicesSaga
from the Dasboard module and creating a customsaga
property on my route. Downside to this is having to import the saga up front. Then, custom code below the routes creates asagaRoutes
object along with theroutesSaga
to use redux-saga-router.If your code still isn’t working, then I’ll need to be able to look at a reproducible example of it not working via a repo or a fiddle in order to offer suggestions.
However, I will reiterate that redux-saga-router is mostly a standalone project that doesn’t offer deep react-router integration besides reusing the history object. There is no way for redux-saga-router to fetch data in response to a route before react-router displays a component for the same route. In fact, I would call that behavior an anti-pattern. If your user clicks on a link, they need some type of immediate feedback, whether that’s a loading message or a spinner. Waiting for data to be fetched with no UI change will create a bad user experience.
One other thing with this boilerplate I thought I should mention. If you only need to fetch your data once, then you really don’t need redux-saga-router in this case. The lazily injected sagas and components will ensure that your dashboard saga is only run once the
/dashboard
route is loaded anyway.Finally, if you’re really looking for a way to fetch data before rendering a component, you could look at redux-tower, but I believe that it requires you to only use it with redux-saga and not use react-router at all. Still, I would recommend ensuring you display some sort of spinner or loading message while waiting on data to come back from an API.
Closing old issue.