When developing front-ends, handling asynchronous behavior is always bit of a challenge. Yassine Elouafi 's redux-saga provides one solution to this problem. Read on to learn more about sagas and redux-saga in particular.
I live in Tangier Morocco and work on a real estate company. I have a lot of passion for coding and learning and hacking new things, exploring Side Effect - Never Ending Saga ideas. Nope well yes and no, I'm graduated in Finances not in CS. I'm a self taught programmer. I hack things for myself, my company and occasionally others. Redux middleware is an add-on you plug into Redux to get additional features. Redux is an opinionated library for managing the state of an application.
Without middleware, all we can do in Redux is compute a new state from the previous state and a given action through reducers which are pure functions. All the handling inside reducers is synchronous and pure.
But in real Carribean Cutle - James McMillan - Savoy V .Quiet Money - The Rematch we need also to do things that are asynchronous may not complete immediately like an AJAX request and impure change the state of the outside world, like saving to a database. In functional programming FP jargon we commonly refer to those things as side effects.
The redux-saga middleware isolates all side effects into software artifacts called sagas so that side effects can be managed. The term saga was historically used by Hector Garcia-Molina and Kenneth Salem to define a mechanism to handle long lived transactions in database systems. But in redux-sagaThe closest meaning is actually a process manager basically: "a process that receive events, and may emit new events sync or asyncaiming to orchestrate complex workflows inside your application" kudos to slorber.
I want to emphasize that you don't actually have to go through academic papers and backend concepts in order to use redux-saga. It's sufficient to know that a saga is a piece of code which runs in the background, watch for dispatched actions, may perform some async calls or synchronous impure calls like browser storage and can dispatch other actions to the store. Sagas are implemented using generator functions a new ES feature.
To understand how saga works, I'll illustrate with a fairly common example and compare with redux-thunkthe idiomatic way to handle async actions in Redux. Suppose we want to request some data from a given url each time an UI Button The Mind Eraser - Canaan - Of Prisoners, Wandering Souls And Cruel Fears clicked. With redux-thunk we'll write a thunk which will typically look like:.
Then, assuming the thunk middleware is mounted in the Redux store, we can Slab Kings - Lil Keke* - Da Leak the above function like this:. That is, You write the task to be performed the fetchUrl which return the thunk. And you invoke that task directly from UI components.
If you don't want to pollute your React components with business logic, Fragment Nederland-Schotland - Various - Bedankt Willem! thunks are a Side Effect - Never Ending Saga simplest and the most idiomatic way to perform side effects in Redux.
However, they may have some drawbacks:. In redux-sagathings are slightly different. First, UI Components never invoke the tasks themselves, instead they always dispatch plain object actions to notify that something happened in the UI:.
The middleware takes care of the real execution then hands the result back to the generator. Once we get a matching action, the middleware will resume the generator with the result which is the action object. The next instruction fork fetchUrl, action. Now the middleware will invoke the fetchUrl Generator but without blocking watchFetchRequests.
Similarly, in fetchUrlwe used call fetch, url to instruct the middleware to call the fetch function.
But this time, the call is blockingthe Side Effect - Never Ending Saga will suspend the generator until the Promise returned by fetch is resolved or rejected then resume the generator with the resolved value or throw with the rejected error.
It may sound like a lot of indirection, but this separation between effect creation and execution makes it really simple to test the logic inside generators. For example, we can test fetchUrl simply by iterating over the generator and inspecting the yielded effects:.
And since generators are stateful, we have much more flexibility to coordinate concurrent tasks. For example, if we want to cancel any pending fetch whenever we request Side Effect - Never Ending Saga new fetch, we can store a reference to the current task in a local variable and use the cancel effect:.
In other solutions, you'll typically have to mock all the surrounding environment which can make the tests very complicated and less reliable. The library also provides primitives and operators to manage concurrency between tasks e. You can fork multiple background tasks in parallel.
You can also cancel a running task. This makes the components more reusable in different contexts. A saga can also act as a decoupling point between 2 parts of the UI, by listening for events from one part and emitting actions that may update another part of the UI.
Without any part being aware of the other part. It all started with an article I wrote about virtual DOM and a functional front-end architecture inspired by Elm. The architecture makes it possible to write the entire web application using pure functions.
After finishing the article, I was looking for the possible ways to introduce side effects. Elm has already introduced the concept of Declarative Effects effects as data. I started a discussion in the functional-frontend-architecture repository which turned out to be immensely useful. Sebastien Lorber slorber introduced me to the Niepokonani - Manifest (19) - Infamia of Sagas as process managers : a kind of background threads which listen for incoming events and can emit themselves other events.
Although my initial focus was not on Redux, I started playing with the idea as a Redux middleware and later realized I could have a more powerful implementation using Generators and by introducing the take effect.
Instead of subscribing to Redux actions and continually invoke a piece of code the handler each time an action is dispatched. I could describe the concept of waiting an action as a normal function call which would block the generator until the expected action is dispatched. This would offer a lot more flexibility to describe complex async flows. I was recently looking at Glimmer the rendering engine behind Ember which has some interesting ideas borrowed from Functional Reactive Programming FRP.
Basically it's a kind of a pull based model no subscription or change propagation through listeners which is a concept I'm very attached to. Hard to tell. There are more and more people using redux-saga but front-end development is continually evolving and the community is more receptive to innovations more than in other languages like Java for example. There seems to be an increasing interest on static typing. There is also a trend toward declarative data fetching GraphQL, Falcor although less marked perhaps because Side Effect - Never Ending Saga solutions are still very young and evolving.
Can you tell a bit about yourself? How would you describe redux-saga to someone who has never heard of it? It is a Redux middleware for handling side effects. Redux Middlewares Redux middleware is an add-on you plug into Redux to Side Effect - Never Ending Saga additional features.
Sagas The term saga was historically used by Hector Garcia-Molina and Kenneth Salem to define a mechanism to handle long lived transactions in database systems. How does redux-saga work? Requesting Data Using redux-thunk Suppose we want to request some data from a given url each time an UI Button is clicked. However, they may have some drawbacks: In order to test the logic inside thunks, you must mock all invoked functions, including the store methods.
Coordinating concurrent tasks can be difficult: If you want to cancel a pending fetch whenever a new fetch is triggered, you'll have to use the Redux store to keep track of the control state whether the previous fetch is still running or not. It might not be that difficult for simple concurrency requirements but can get quickly become awkward. Business logic tends to be scattered in various places: startup modules, components, and thunks themselves. Requesting Data Using redux-saga In redux-sagathings are slightly different.
But this time, the call is blockingthe middleware will suspend the generator until the Promise returned by fetch is resolved or rejected then resume the generator with the resolved value or throw with the rejected error It may sound like a lot of indirection, but this separation between effect creation and execution makes it really simple to test the logic inside generators.
Why did you develop redux-saga? What next?
Mi Linda Barbara - Various - La Cumbia Con Cucharita, Vorwärts, All Right - Warlock - True As Steel, Choral: Schaut Hin, Dort Liegt Im Finstern Stall - Various - Les Plus Belles Pages De La Musique Sac, The Light Of Love - Humble Pie - Natural Born Bugie - The Immediate Years