Skip to content

Commit

Permalink
Update saga middleware options to reflect implementation (#2372)
Browse files Browse the repository at this point in the history
We already allowed `channel` to be passed into `createSagaMiddleware`,
this change simply updates our types to match our implementation.

I also added a recipe for batching redux actions since it is a very
common paradigm and something I've had to re-write multiple times from
memory.

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
  • Loading branch information
neurosnap and Andarist authored Mar 17, 2023
1 parent daf805c commit 2cccf48
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .changeset/eighty-lions-sleep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@redux-saga/core': patch
'redux-saga': patch
---

Added a `channel` property to the `SagaMiddlewareOptions` to reflect its runtime support.
3 changes: 2 additions & 1 deletion docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ Creates a Redux middleware and connects the Sagas to the Redux Store

- `onError: (error: Error, { sagaStack: string })` - if provided, the middleware will call it with uncaught errors from Sagas. useful for sending uncaught exceptions to error tracking services.
- `effectMiddlewares` : Function [] - allows you to intercept any effect, resolve it on your own and pass to the next middleware. See [this section](advanced/Testing.md#effectmiddlewares) for a detailed example

- `channel`: If provided, the middleware will use this channel instead of the default `stdChannel()` for
* `take` and `put` effects.

#### Example

Expand Down
43 changes: 43 additions & 0 deletions docs/Recipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,3 +214,46 @@ function* main() {
}
}
```

## Batching actions

`redux` does not support the ability to dispatch multiple actions and only call
the reducer once. This has performance implications and the ergonomics of
needing to dispatch multiple actions sequentially aren't great.

Instead we look to a third-party library, [redux-batched-actions](https://github.com/tshelburne/redux-batched-actions). This is a
simple reducer and action that allows end-developers to dispatch multiple
actions and only have your reducer be called once.

If you have a codebase that needs to dispatch many actions at the same time, we
recommend using this recipe.

```javascript
import { configureStore } from '@reduxjs/toolkit';
import createSagaMiddleware, { stdChannel } from 'redux-saga';
import { enableBatching, BATCH } from 'redux-batched-actions';

// your root reducer
import { rootReducer } from './reducer';
// your root saga
import { rootSaga } from './saga';

const channel = stdChannel();
const rawPut = channel.put;
channel.put = (action: ActionWithPayload<any>) => {
if (action.type === BATCH) {
action.payload.forEach(rawPut);
return;
}
rawPut(action);
};
const sagaMiddleware = createSagaMiddleware({ channel });

const reducer = enableBatching(rootReducer);
// https://redux-toolkit.js.org/api/configureStore
const store = configureStore({
reducer: rootReducer,
middleware: [sagaMiddleware],
});
sagaMiddleware.run(rootSaga);
```
5 changes: 5 additions & 0 deletions packages/core/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ export interface SagaMiddlewareOptions<C extends object = {}> {
* next middleware.
*/
effectMiddlewares?: EffectMiddleware[]
/**
* If provided, the middleware will use this channel instead of the default `stdChannel` for
* take and put effects.
*/
channel?: MulticastChannel<Action>;
}

export interface SagaMiddleware<C extends object = {}> extends Middleware {
Expand Down
5 changes: 5 additions & 0 deletions packages/core/types/ts3.6/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ export interface SagaMiddlewareOptions<C extends object = {}> {
* next middleware.
*/
effectMiddlewares?: EffectMiddleware[]
/**
* If provided, the middleware will use this channel instead of the default `stdChannel` for
* take and put effects.
*/
channel?: MulticastChannel<Action>;
}

export interface SagaMiddleware<C extends object = {}> extends Middleware {
Expand Down

0 comments on commit 2cccf48

Please sign in to comment.