Skip to content

Instantly share code, notes, and snippets.

@jawad-aziz-farhad
Last active December 16, 2021 12:47
Show Gist options
  • Save jawad-aziz-farhad/45e1bf31eef4e2d92207eb5fc3f9734f to your computer and use it in GitHub Desktop.
Save jawad-aziz-farhad/45e1bf31eef4e2d92207eb5fc3f9734f to your computer and use it in GitHub Desktop.
A small demonstration of the implementation of State management using Redux and Redux-Saga for side effects in MERN Stack App.
// All api calls through this file
import axios from "axios";
const SERVER_URL = process.env.REACT_APP_SERVER_URL
export async function getAPIRequest(payload, isAutenticationRequired = true){
try {
return await (await axios.get(`${SERVER_URL}${payload.endPoint}`, isAutenticationRequired ? { withCredentials: true } : {} )).data
} catch(error) {
return error;
}
}
export async function postAPIRequest(payload, isAutenticationRequired = true ){
try {
return await (await axios.post(`${SERVER_URL}${payload.endPoint}`, payload.payload, isAutenticationRequired ? { withCredentials: true } : {} )).data
} catch(error) {
return error;
}
}
export async function deleteAPIRequest(payload, isAutenticationRequired = true ){
try {
return await (await axios.delete(`${SERVER_URL}${payload.endPoint}`, isAutenticationRequired ? { withCredentials: true } : {} )).data
} catch(error) {
return error;
}
}
import { all, call } from "@redux-saga/core/effects"
import userSaga from "./user-saga"
// Import All Other Sagas
export default function* rootSaga(){
yield all([
call(userSaga)
])
}
import { put } from "@redux-saga/core/effects"
import { showNotification } from "redux/slices/notification-slice"
export default function* showNotificationSaga({message, data = { success: false} }) {
yield put(showNotification({
type: 'SHOW-NOTIFICATION',
message: `${message}` || `Oops! Something went wrong.`,
data
}))
}
import { createSlice } from '@reduxjs/toolkit'
export const notificationSlice = createSlice({
name: 'notification',
initialState: {
type: '',
message: '',
data: '',
},
reducers: {
showNotification: (state, action) => {
state.type = action.payload.type
state.message = action.payload.message
state.data = action.payload.data
}
}
})
export const { showNotification } = notificationSlice.actions
export default notificationSlice.reducer
A small demo for implementing state management using redux and redux-saga (for side effects)
import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit";
import createSagaMiddleware from "@redux-saga/core";
import rootSaga from "./sagas"; // From Sagas' index file
import userSlice from "./slices/user-slice";
import notificationSlice from "./slices/notification-slice";
// Other Slices
const sagaMiddleware = createSagaMiddleware()
const middlewares = [sagaMiddleware]
const store = configureStore({
reducer: {
user: userSlice,
notification: notificationSlice
},
middleware: [...getDefaultMiddleware({thunk: false}), ...middlewares],
devTools: process.env.NODE_ENV !== 'production'
})
sagaMiddleware.run(rootSaga)
export default store
import { put, takeLatest, call } from 'redux-saga/effects'
import { getAPIRequest, postAPIRequest } from 'redux/api-requests'
import { getUser, setUser, signIn, signInError, signOut } from 'redux/slices/user-slice'
import showNotificationSaga from './notification-saga'
function* getUserSaga() {
try {
const data = yield call(getAPIRequest, {endPoint: 'user'})
if (data.email) {
yield put(setUser({data}))
}
} catch (error) {
yield call(showNotificationSaga)
}
}
function* signInSaga({payload}){
try {
const data = yield call(postAPIRequest, {endPoint: 'login', payload: payload.payload})
if (data.hasOwnProperty('uuid')) {
yield call(getUserSaga)
} else {
yield put(signInError({data}))
}
} catch(error) {
yield call(showNotificationSaga)
}
}
function* signOutSaga(){
try {
const data = yield call(getAPIRequest, {endPoint: 'logout'})
if (data.success) {
yield put(setUser({}))
}
} catch(error) {
yield call(showNotificationSaga)
}
}
export default function* userSaga() {
yield takeLatest(getUser, getUserSaga)
yield takeLatest(signIn, signInSaga)
yield takeLatest(signOut, signOutSaga)
}
import { createSlice } from '@reduxjs/toolkit'
export const userSlice = createSlice({
name: 'user',
initialState: {
user: null,
isLoggedIn: false,
signInError: null,
},
reducers: {
signIn: () => {},
signInError: (state, action) => {
const { data } = action.payload
state.signInError = data ? {...data} : null
},
signOut: () => {},
setUser: (state, action) => {
const { data } = action.payload
if(data) {
state.user = {...data}
state.isLoggedIn = true
} else {
state.user = null
state.isLoggedIn = false
}
},
getUser: () => {},
updateUser: () => {}
}
})
export const { setUser, getUser, updateUser, signIn, signInError, signOut } = userSlice.actions
export default userSlice.reducer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment