Getting callbacks from redux-saga

Viewed 193

I am triggering a function in saga with Dispatch. Can Saga send me information inside the component after it's done all its work? Actually, I will explain what I want to do with a simple example, don't laugh, please, I am sure this won't work.

dispatch({
  type: 'triggerApiCallInSaga'
}).then(res => doSomething(res.payload));

I want to make changes in the component as a result of the query I have made. I actually want to maintain this with redux, but I'm worried about my state expanding. Also it seems silly to me to check via redux to close the modal.

In short I want to receive signal from saga and see it in component. Can I make a listener for it? Or does saga have a method for this? Although I searched, I could not find the right results. redux-sagas callback (aka sagas and setState) I encountered a similar question to my question, but here I encountered a negative answer that I did not understand.

Thank you.

1 Answers

The answer you linked is right, the expected way for a saga to communicate back to component is through updating redux store. Adding promises/callbacks is an antipattern, because each action can be handled by 0-n sagas - of course you might know in your case it is just one saga, but the framework doesn't guarantee that in any way and so it can lead to some unexpected issues later on.

That said, even though it is an antipattern doesn't mean you can't do it.

The easier way is to add an callback to the action, so e.g.

// component
const callback = data => console.log(data)
dispatch({type: MY_ACTION, callback})

// saga
yield takeEvery(MY_ACTION, function*(action) {
  action.callback({foo: 'bar'});
})

If you would prefer promises, that is something that can't be done easily with just the saga library, but there are packages that can add this functionality like: https://github.com/adobe/redux-saga-promise

Ideal solution to this problem would be to run a saga on top of a useReducer hook, so that instead of adding component specific state to redux store you would just work with a component state. There are some attempts out there that try to do this, but unfortunately react is still missing some functionality that would allow us to reliably do this without introducing other issues.

Related