// there are two types of ways to use the middleware in redux , and each type has own application usecases
// one is for custom middleware , before any change in the stete it runs
// we can create that somthign like this |
export const Authneticate = (store) => (next) => (action) => {
if (!store.getState().user.isLoggin) {
console.log("user is not login )
return;
}
const reslt = next(action) // forword to the next state where reducer will work on
and thesimply return the result
return reslt
}
const AppStore = configureStore({
reducer : {
user: userReducer
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(Authneticate)
})
// antoher way is useing thunk of the react redux
// we can create this with the extraReducer
const fetchUser = creatAsynThunk(
'user/fetchuser',
async(_, thunkApi) => {
try {
const response = await fetch('https://api.example.com/products');
if (!response.ok) throw new Error('Server error occurred');
const data = await response.json();
return data; // This becomes the action.payload inside 'fulfilled'
} catch (error) {
return thunkAPI.rejectWithValue(error.message); // This goes to 'rejected'
}
}
)
// every asynthunk middleware has three states pending , fullfilled , rejected
const useSlice = createSlice({
name: "user",
initialState: {
user: null,
loading: false,
error: null
},
reducer: {
setUser: (state, action) => {
state.user = action.payload
},
clearUser: (state) => {
state.user = null
}
},
extraReducers: (builder) => {
builder
.addCase(fetchUser.pending, (state, action ) => {
state.loading = true
})
.addCase(fetchUser.fulfilled, (state,action) => {
state.loading = false
state.user = action.payload
})
.addCase(fetchUser.rejected, (state,action) => {
state.loading = false
state.error = action.payload
})
}
})