Created
July 16, 2025 09:19
-
-
Save agilworld/5d74022f76d5d8be1a2d224aa12a59aa to your computer and use it in GitHub Desktop.
Create Loading UI Middleware with React Context & Redux JS toolkit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, useEffect } from 'react'; | |
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; | |
import { LoadingProvider, useLoading, setLoadingFunction } from './contexts/LoadingContext'; | |
function App() { | |
return ( | |
<LoadingProvider> | |
<LoadingFunctionSetter /> | |
<MainContent /> | |
</LoadingProvider> | |
); | |
} | |
function LoadingFunctionSetter() { | |
const { setIsLoading } = useLoading(); | |
useEffect(() => { | |
setLoadingFunction(setIsLoading); | |
}, [setIsLoading]); | |
return null; | |
} | |
function MainContent() { | |
const { isLoading } = useLoading(); | |
return ( | |
<> | |
{isLoading && <LinearProgress sx={{zIndex:1500}} color="warning" />} | |
<Router> | |
<Routes> | |
<Route path="/login" element={<Login />} /> | |
{/* Redirect root to dashboard or login */} | |
<Route path="/" element={<Navigate to="/dashboard" replace />} /> | |
{/* Protected dashboard routes */} | |
<Route | |
path="/dashboard" | |
element={ | |
<ProtectedRoute requireRole={['superadmin', 'manager']}> | |
<Dashboard /> | |
</ProtectedRoute> | |
} | |
/> | |
{/* Catch-all route for 404 */} | |
<Route path="*" element={<Navigate to="/dashboard" replace />} /> | |
</Routes> | |
</Router> | |
</> | |
); | |
} | |
export default App; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { createContext, useState, useContext } from 'react'; | |
interface LoadingContextType { | |
isLoading: boolean; | |
setIsLoading: (isLoading: boolean) => void; | |
} | |
const LoadingContext = createContext<LoadingContextType | undefined>(undefined); | |
export const LoadingProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { | |
const [isLoading, setIsLoading] = useState(false); | |
return ( | |
<LoadingContext.Provider value={{ isLoading, setIsLoading }}> | |
{children} | |
</LoadingContext.Provider> | |
); | |
}; | |
export const useLoading = () => { | |
const context = useContext(LoadingContext); | |
if (context === undefined) { | |
throw new Error('useLoading must be used within a LoadingProvider'); | |
} | |
return context; | |
}; | |
// Create a ref to store the setIsLoading function | |
let setLoadingRef: ((isLoading: boolean) => void) | null = null; | |
// Function to set the ref | |
export const setLoadingFunction = (func: (isLoading: boolean) => void) => { | |
setLoadingRef = func; | |
}; | |
// Function to be used in middleware | |
export const setLoadingState = (isLoading: boolean) => { | |
if (setLoadingRef) { | |
setLoadingRef(isLoading); | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Middleware } from '@reduxjs/toolkit'; | |
import { setLoadingState } from '../contexts/LoadingContext'; | |
const loadingMiddleware: Middleware = () => (next) => (action:any) => { | |
if (action.type.endsWith('/pending')) { | |
setLoadingState(true); | |
} else if (action.type.endsWith('/fulfilled') || action.type.endsWith('/rejected')) { | |
setLoadingState(false); | |
} | |
return next(action); | |
}; | |
export default loadingMiddleware; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment