-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Code splitting / dynamically loading sagas #76
Comments
Actually yes. But there are some issues with the actual method runSaga (see #48). Sagas started by runSaga can't see actions from sagas started by the middleware
Not a middleware but a store enhancer. There are some potential issues with this approach (see #13 (comment)) It seems the solution proposed by @gaearon (#48 (comment)) is the simplest one; a
Didn't think about this. But If we provide a way to dynamically attach sagas to the middleware, it makes sens to be able to detach them. I think we can do this by providing exposing a cancel method
I don't see any issue with that |
So basically as it stands now its not possible, but an "official" api (run method within the middleware) is being considered? I just wanted to make sure I didn't miss anything from the current API as I am new to sagas. |
for now you can use runSaga but only if your dynamic Sagas don't take actions from middleware-Sagas. Otherwise yes, it's not possible
Yes exactly. I think I'll go with that. should be probably this week-end if things go well |
Usually in Redux we try to return a function for this, e.g. |
Actually |
Ah, okay then! |
FYI new 0.7.0 version is out with the new method of running dynamic sagas |
I haven't tried this out yet but this is the pseudocode I will be experimenting with. // app
import createSagaMiddleware from 'redux-saga'
const rootReducer = createReducers(reducerRegistry.getReducers());
const sagaMiddleware = createSagaMiddleware(sagaRegistry.getSagas());
const store = createStore(
rootReducer,
initialState,
applyMiddleware(sagaMiddleware)
);
reducerRegistry.setChangeListener(reducers => {
store.replaceReducer(createReducer(reducers));
});
sagaRegistry.setChangeListener(sagas => {
sagaMiddleware.run(sagas);
});
// routes
function createRoutes(reducerRegistry, sagaRegistry) {
return <Route path="/" component={App}>
<Route path="async" getComponent={(location, cb) => {
require.ensure([], require => {
reducerRegistry.register(require('./reducers').default);
sagaRegistry.register(require('./sagas').default);
cb(null, require('./views/Index').default);
});
}}/>
</Route>
} |
@patrickheeney I was implementing something similar recently for code splitting with both reducers and sagas. Its working quite well, although the sagaRegistry has to be implemented a bit differently from the reducerRegistry. With reducers, you can easily trigger With the sagas, however, it would be incorrect to both (1) run the all the sagas store in the registry and (2) re-run sagas that have been started for the route. (1) is pretty easy to solve by just only sending to the change listener the new saga Im currently doing (1) and (2b) but I'd be interested to hear how others tackle the problem |
Closing this, feel free to add your comments. I can reopen it if needed. |
I don't quite understand the code split with the reducers. Care to elaborate on that? |
@pke check out reduxjs/redux#37 for more details on code splitting with reducers. Its got a great explanation by Dan Ambramov about the process and workflow. |
@mjrussell I'm at the stage now where I need to implement the saga library. I'm still new to sagas, which is probably why this is a bit harder for me right now. I am trying to figure out how to do hot-reloading and code-splitting for sagas. Would you mind sharing your approach? I realize that i can call Maybe @yelouafi can chime in too :) One way I figured it might work is by storing the returned tasks for each |
@johanneslumpe AFAIK you cannot hot-reload a saga. Changes to sagas during hot reloading should force an entire app refresh. What I do is pass in a "key" of the saga to a registry which calls |
@mjrussell that's the way I went for now - only adding new sagas to the store and passing them to |
Hello there, I had the same issue and found redux-injector for injecting reducers asynchronously via routing. You can find an exemple in the README. Hope you'll enjoy it 🎉 PS: It also works with SSR Stream Caching and with react-redux >= 6.0.0 |
We recently built a library called redux-dynamic-modules. The library helps in code splitting Redux applications and allows loading reducers, middlewares, sagas dynamically. It also comes with a HOC to load/unload a module when the component requiring them mounts or unmounts. |
@navneet-g cool library, any roadmap to support |
@luskin we use |
@navneet-g Is this issue irrelevant then? |
When using immutable with
|
Thanks @luskin , let us continue the discussion on the issue there. Seems like Alex plans to take a stab at it. |
how to use?
|
Hi @dthtien I've recently updated my public website using this technology. |
I just discovered
redux-saga
and I am looking to start integrating this into my app. I am currently code splitting my reducers and using replaceReducer when they hit the correct route. From the saga examples it looks like they all use a rootSaga. The closest I found to an answer is #23 (comment) but I am not certain if this is the official API and usage.My current setup looks something like this: http://stackoverflow.com/a/33045558 which I pasted a snippet below:
From the other comment, it sounds like this should be possible, but it looks like sagas need access to the store?
It looks like a middleware approach was discussed in #13 (comment) that would have solved this, but it was closed. This could have potentially worked:
Would this be the official usage? What about "stopping/removing/disconnecting" the sagas? Will this work with server side rendering?
The text was updated successfully, but these errors were encountered: