redux-saga
redux-saga copied to clipboard
Custom effects
Just look into what it would take to add such functionality
I want to use logux with redux-saga, but it needed an opportunity to use custom dispatch function:
Instead of Redux, in Logux Redux you have 4 ways to dispatch action:
-
store.dispatch(action)
is legacy API. Try to avoid it since you can’t specify how clean this actions. -
store.dispatch.local(action, meta)
— action will be visible only to current browser tab. -
store.dispatch.crossTab(action, meta)
— action will be visible to all browser tab. -
store.dispatch.sync(action, meta)
— action will be visible to server and all browser tabs.
I think it could be solved by implementing custom effect like PUT_LOCAL
. Are there any updates about this issue?
@borovik96 custom effects topic is progress, but I suspect you can implement it right now with emitter
option https://github.com/redux-saga/redux-saga/blob/master/packages/core/test/middleware.js#L105-L113
@borovik96 your use case seems simple enough that using lower-level runSaga
API should get you everything you need. You'd have to provide a specialized dispatch
to runSaga
that would interpret input action based on some prop and would use appropriate logux
dispatch flavour accordingly, so you could just use smth like
yield put({ type: 'SOME_TYPE', meta: { crossTab: true } })
where ofc you could hide this behind a helper function
const putCrossTab = ac => put({ ...ac, meta: { ...(ac.meta || {}), crossTab: true } })
I need an effect to handle call
and logging
for each API call for me, for now I have a universalCall
function which call fetch in nodejs and browser for me. It is async function and I have await in it. I want to call yield put(logActions.writeLog(logInfo));
before and after API call.
Do you think it is good to have callAndLog
custom effect and do logging inside it?
@sayjeyhi Possibly I will do logging with saga monitor like this,
class MyMonitor implements SagaMonitor {
private _trackIds = {};
private _filter: string[] = [];
setCallApiFunctionNames(list: string[]) {
this._filter = [...list];
}
effectResolved(effectId: number, result: any): void {
if (this._trackIds[effectId]) {
this._trackIds[effectId] = Object.assign({}, this._trackIds[effectId], {
end: new Date().getTime()
});
// console.log(this._trackIds);
}
}
effectTriggered(options: {
effectId: number;
parentEffectId: number;
label?: string;
effect: any;
}): void {
if (options.effect.type === "CALL"
&& options.effect.payload.fn.name
&& this._filter.some(fn => fn === options.effect.payload.fn.name)) {
this._trackIds[options.effectId] = {
start: new Date().getTime(),
functionName: options.effect.payload.fn.name
};
}
}
}
const monitor = new MyMonitor();
monitor.setCallApiFunctionNames(["getCosts"]);
const sagaMiddleware = createSagaMiddleware({
sagaMonitor: monitor
});
I had a chat with andarist and we decided to not implement this feature. Instead, if we want to add more effects, we could create a superset library that provides more effects.