Hello There.

I will be telling you the story of how data flows into the Redux.

Before Start let’s know the characters:

Actions: To define the constants and functions that help us to take request from view.

Reducers: For updating stored data in store.

Sagas: Middle-ware for calling the API’s.

Stores: Source of truth to store data.

Note: You can change characters as you want it’s your story. (Only Middle-ware :))

Now we can start:

First we have to configure our store.

import { Provider } from 'react-redux';
import configureStore from 'appState/stores/configureStore';
const store = configureStore();
<Provider store={store}>
<MyComponent />
</Provider>

In stores/configureStore.js

import { createStore, applyMiddleware, compose } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootSaga from 'appState/sagas';
import reducers from 'appState/reducers';
const sagaMiddleware = createSagaMiddleware();const initialState = {};/* eslint-disable no-underscore-dangle */
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware));
/* eslint-enable */
const store = createStore(reducers, initialState, enhancer);export default function configureStore() {
sagaMiddleware.run(rootSaga);
return store;
}

Second we have to add some constants and actions

in actions/constants/my_component.actions.js

export const MY_COMPONENT_REQUEST =
'my_component/MY_COMPONENT_REQUEST';
export const MY_COMPONENT_SUCCESS =
'my_component/MY_COMPONENT_SUCCESS';
export const MY_COMPONENT_FAILURE =
'my_component/MY_COMPONENT_FAILURE';

in actions/ActionCreators.js

import {
MY_COMPONENT_REQUEST
} from './constants/my_component.actions';
const generateActionCreator = type => (payload, error = false) => ({
type,
payload,
error
});
export const fetchMyComponent = generateActionCreator(
MY_COMPONENT_REQUEST
);

Third we have to add the API request into the sagas(Middle-ware)

import { call, put, takeLatest } from 'redux-saga/effects';
import { axiosDefault } from 'axios-setup';
import {
MY_COMPONENT_REQUEST,
MY_COMPONENT_SUCCESS,
MY_COMPONENT_FAILURE
} from 'appState/actions/constants/my_component.actions';
function* fetchComponents() {
try {
const response = yield call(axiosDefault.get, `/components`);
yield put({
type: MY_COMPONENT_SUCCESS,
payload: {
products: response.data
}
});
} catch (e) {
yield put({
type: MY_COMPONENT_FAILURE,
payload: { error: e },
error: true
});
}
}
export default function* myComponentFetch() {
yield takeLatest(MY_COMPONENT_REQUEST, fetchComponents);
}

also in sagas/index.js

import { all } from 'redux-saga/effects';
import * as myComponentSagas from './MyComponent';
export default function* rootSaga() {
yield all([
...Object.keys(myComponentSagas).map(func => myComponentSagas[func]())
]);
}

Fourth we have to set our reducer for initial state and the updated state after the success is called:

// linting rules disabled for immer js
/* eslint-disable consistent-return */
/* eslint-disable no-param-reassign */
import produce from 'immer';
import { MY_COMPONENT_SUCCESS } from 'appState/actions/constants/my_component.actions';
const initialState = {
components: []
};
export default function MyComponentReducer(state = initialState, action) {
return produce(state, draft => {
switch (action.type) {
case MY_COMPONENT_SUCCESS: {
const { components} = action.payload.components;
draft.components = components;
return;
}
default:
return draft;
}
});
}

also in reducers/index.js

import { combineReducers } from 'redux';
import component from './MyComponentReducer';
const appReducer = combineReducers({
component
});
const rootReducer = (state, action) => {
return appReducer(state, action);
};
export default rootReducer;

Finally How we are gonna use this in our component:

import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import {
fetchMyComponent
} from 'appState/actions/ActionCreators';
const structuredSelector = createStructuredSelector({
components: state => state.components.components
});
// Below Lines should be inside the component
const {
components
} = useSelector(structuredSelector);
const dispatch = useDispatch();dispatch(fetchMyComponent());

Hope you like the Story.

Developer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store