Let’s build Redux-Saga from scratch
¿Have you wonder about how some state-management libraries works under the hood? ¿Have you notice that Redux needs extensibility in order to manage asynchronous capabilities?¿why Redux-Saga? This is gonna be pure evil magic
Stop this madness and show me the code
Filetree Project
We’ll be working on a File tree Component so anything that resembles to:
It provides capabilities such as:
- open/hide directory children
- keep state between renderings. If a children is open or hidden and its parent open/hide. The children should state the same (useReducer),
- should fetch data from an API (async generators)
Redux-like behaviour
For those of us who had some familiarity with state management and its complexities really want predictability in state transitions, that is what Redux model bring to us.
Luckily for us there is a hook that provide us redux capabilities but keep the state local to components, useReducer. But first let’s define our reducer.
The important takeaway from the previous code:
- is that ‘set_expanded’ action will open and hide directories and only take the directory name as an argument.
and will use it(the reducer) on our code like,
Keep your eyes on that dispatch function because we’ll use it to trigger state transitions (send actions).
Context
Now, everything seems smooth but we have an issue we want to resolve right away. Our dispatch is available just in our root component and we are going to need to trigger state transitions from very far away children components (and avoid props drilling). But the react team has solved this issue long time ago. So, not a problem? right.
Yeah, Context will allow us to put our dispatch function any place on the tree we need it.
“Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.”
This model for handling state looks fine when comes to synchronous state transitions but what about async transitions. For instance when we need to fetch data from some API or subscribe to an event handler.
Now when it comes to asynchronous behaviour in Redux world they solved it extending redux capabilities through a middleware. The guy who sits between the app reducer and every action dispatched into the application.
Generators
Generators are a way to produce iterator objects (the ones who produces values over an iteration loop).
So we get it, generator are a way to produce values over time. .
We’ll use it to intercept every action it comes to our app reducer.
Async Generators
Generators are great but they aren’t a great fit to our application just yeah since we keep our state transitions synchronous. Let’s make SET_INIT_DATA transition async and request some data from an API.
Cool, now looks promising every time our application trigger set_init_data action our generator will intercept it, request some data and call our reducer for us.
Redux-Saga like but cooked at home
Now let’s put all the pieces together and see what we have come across: