Introduction to Redux - Saga
By: Tharindu Chathuranga
Tags: Redux Saga, React State, React, Redux

Let’s talk more about redux

Well, to be honest when I learn redux for the first time I was really confused. Too much of new terminology such as actions, reducers, middleware, store etc and I had no clue how this things connect to each other.

But don’t worry, eventually you will realise how things work together.

Redux Store

Let’s get back to the topic. So Redux Store holds all of the application’s state. So let’s create a store and look how it’s work.

npm i redux react-redux

After installing those packages, create a folder called store inside the src folder. Then add following code in index.js file.

import { createStore } from 'redux'

import rootReducer from './root.reducer.js'



const store = createStore(rootReducer) export default store

Redux Reducers

A reducer is a JavaScript function which takes two parameters called state and action.

In a typical React component the local state might be mutated in place. In Redux you’re not allowed to do that. The third principle of Redux (as outlined by its creator) prescribes that the state is immutable and cannot change in place.

Below is an example reducer. Here we have pass the initial state. So this reducer does nothing other than returning the initial state.

const initialState = {

data: []

}



function exampleReducer(state = initialState, action) {

return state

}





export default exampleReducer

Confused? yah I was too. But you will understand everything please continue. We will create a meaning full reducer file later.

Redux Actions & Constants

Reducers are one of the main concept in redux because it generate the state of the application. But how does it knows when to generate the next state? for that we need Actions and constants.

The second principle of Redux says the only way to change the state is by sending a signal to the store. This signal is an action. So “dispatching an action” means sending out a signal to the store.

Let’s have a look on constants. I’m going to develop a simple weather dashboard using React — Redux saga. So create a folder called weather inside store folder and create a file called weather.constants.js

weather.constants.js

weather.actions.js

This is the action. As you can see it is a JavaScript object with two properties: type and payload.

The type property means how the state should change and it is required by Redux.

The payload property means what should change in the state and it is optional. which means if you don’t have new data to save in the store you can omit payload.

Still wondering why do we need constants? see the type property takes a string. Strings are prone to typos and duplicates and for this reason it’s better to declare actions as constants like we did above.

Let’s create weather.reducers.js file.

In this reducer file we have import the weather constants as types.

I have destructured the action parameter that’s why you can see type and payload instead action.

We have a switch case inside the weather function and reducer will return the states according to the current action type.

So like this we can have many reducers for many states in the same application. so we have to combine all of these reducers in a one place.

For that we need root.reducer.js file.

This is the root reducer file. As you can see we will import our each and every reducer file here and will pass them to combineReducers. So we can have all of those reducers in one state.

root.reducer.js

Redux Selectors

What? Selectors? Why do we need selectors?

npm i reselect

we need to install reselect package in order to create selectors.

A selector looks like this. A selector is a small function you write that can take the entire Redux state, and pick out a value from it.

Let’s say you need to get the isLoading state inside your component, if you don’t have a selector you have to get the entire state for that. But with selectors, you can pick what you want.

Now we have created actions, reducers, constants and selectors. Here I’m not going to show about creating a react component, instead I’m going to show how to connect redux into a react component.

Before that, Let’s have a look on Redux — Saga

Redux — Saga

Redux-Saga use generators instead of normal functions. Because of that we are able to test, write and read async calls easily.

STOP! ✋🏻 thinking about generators? read more about generators 👈

Let’s Implement the middleware

First we need to install the package.

npm install redux-saga

Redux Saga has two main function types.

A worker function A watcher function

Watcher is a generator function watching for every action that we are executing. In response to that action watcher will call a worker function. Normally we keep one Watcher function and we can have multiple worker functions in a single saga.

In here getCurrentWeatherStart is a worker function. and weatherSaga is a watcher function

The worker function will make the API call from redux-saga/effects. after the data loaded we will dispatch another action from our saga using put from redux-saga/effects.

Now we need root. (not Joe Root 🤭) we need a root saga like we create root reducer earlier.

So here is the root.sagas.js file. In here we use all from redux-saga/effects. Then we import all the sagas in our application to root saga and call them inside rootSaga generator function.

Now we are going to modify our store. so open the index.js file inside the store folder.

modified store

First import applyMiddleware from redux.

Then install redux-devtools-extention package.

npm i redux-devtools-extension

Then import createSagaMiddleware from redux-saga and then do the modification like above.

Connect component with redux.

Open your component and import connect from react-redux.

Then the action which you want to dispatch from the action file. and then the all the selectors that you need.

In the end of the component file, you have to change above to following code.

mapStateToProps

“As the first argument passed in to connect, mapStateToProps is used for selecting the part of the data from the store that the connected component needs. It’s frequently referred to as just mapState for short.” — https://react-redux.js.org/

It is called every time the store state changes.

It receives the entire store state, and should return an object of data this component needs.

mapDispatchToProps