How to use redux saga with without redux?
Asked Answered
L

2

6

One of my top reasons for using redux-saga is how testable it makes asynchronous function calls. My dilemma is that when I am programming with stateful objects that wouldn't belong inside my redux store it becomes pretty awkward programming with sagas. Is there a best practice for working with non-pure data objects and redux-saga?

Say I have callback functions I register with an API, firebase in this case, and I need to book keep these callback functions so I can unregister them later. I can't store these callback functions in redux, so does it still make sense to write this as a saga?

Seems a bit weird in one piece of code to be able to use things like put, select and in other bits of code I have to use store.dispatch.

Example:

  const childAddedTrigger = (dataSnapshot: firebase.database.DataSnapshot) => {
    const message = Object.assign({}, dataSnapshot.val(), {
      key: dataSnapshot.key,
    });
    service.store.dispatch(Actions.channelMessageAdded(channelId, message));
  }    

  service.firebase.database().ref(`channels/${channelId}/messages`)
    .limitToLast(20)
    .on('child_added', childAddedTrigger);

  this.channelSubscriptions[channelId] = childAddedTrigger;
Lucillelucina answered 9/8, 2016 at 23:1 Comment(5)
can you show an example of your troubles?Niobic
Added a quick example where I want to save callback functions to unregister them later. Can I write this in a more unified saga way?Lucillelucina
Callback finishes cannot be tracked by generators. There isn't a prettier way to work with firebase 'on.'Smuts
Where do I put these callbacks? I can't put them in redux. How do I continue to use the format of saga functions without using a redux store?Lucillelucina
What I'm saying is that you can't. You'll have to be content with using sagas to listen for the actions dispatched by your callback. There is no getting around actually using the dispatch method if you want to stick with firebase node listeners.Smuts
C
6

You would want to use the redux-saga concept of Channels.

The effect's like take, call, put that make async functions so easy to test with redux-saga by default interact with redux's store, because the library is first and foremost a redux middleware.

However, the eventChannel factory function allows you to take external event sources say from a websocket or firebase and 'take' events from them, rather than take actions dispatched from the store and 'put' events to them, rather than to the redux store.

Consignment answered 25/8, 2016 at 0:32 Comment(0)
D
3

What you want is runSaga. It is the function to run any saga by giving everything needed for a saga to work as the arguments.

As stated by @TheBrofessor, since redux-saga works by communicating with some input and output, if you can define such input and output, it is runnable in redux-saga. The channel option and dispatch option is responsible for providing input and output for saga. See documentation for detailed explanation.

One thing to note, which is not documented in the docs, is the behavior of stdChannel. Actually, the channel described in the Channel document behaves like queue. Where as the behavior of stdChannel is rather subscribe/dispatch (just like "channels" in any other subscription framework).

It is because stdChannel is a special channel that is created to behave like subscription channel. In fact, when redux-saga is connected to redux store, it puts all the store's dispatch events into stdChannel, so every saga which is takeing all can receive the dispatched event.

You can confirm redux-saga actually defines notion of multicast in their source code, which is implemented on the stdChannel.

Disyllable answered 19/10, 2019 at 4:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.