Created
April 26, 2022 04:57
-
-
Save javonmcgilberry/dc4d18fccc0cafaeeb9c1b292a14beb5 to your computer and use it in GitHub Desktop.
Redux Store Starter with Next Redux Wrapper
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
| /* eslint-disable @typescript-eslint/no-explicit-any */ | |
| import { | |
| AnyAction, | |
| AsyncThunk, | |
| AsyncThunkPayloadCreator, | |
| combineReducers, | |
| configureStore, | |
| Dispatch, | |
| } from '@reduxjs/toolkit'; | |
| import { | |
| nextReduxCookieMiddleware, | |
| wrapMakeStore, | |
| } from 'next-redux-cookie-wrapper'; | |
| import { createWrapper, HYDRATE } from 'next-redux-wrapper'; | |
| import { LOGOUT } from '../redux/user'; | |
| /** | |
| * Whatever redux slice key value is placed in this array, its information will be stored as a cookie | |
| * so the information will persist. | |
| */ | |
| const PERSISTED_REDUCERS = ['']; | |
| const combinedReducer = combineReducers({}); | |
| const reducer = (state: any, action: AnyAction) => { | |
| // logout action clears state; | |
| if (action.type === LOGOUT) { | |
| clearReduxStateOnLogout(action); | |
| } | |
| if (action.type === HYDRATE) { | |
| const nextState = { | |
| ...state, // use previous state | |
| ...action.payload, // apply delta from hydration | |
| }; | |
| return nextState; | |
| } else { | |
| return combinedReducer(state, action); | |
| } | |
| }; | |
| const clearReduxStateOnLogout = (action: AnyAction) => { | |
| return combinedReducer(undefined, action); | |
| }; | |
| export const store = configureStore({ | |
| reducer, | |
| middleware: (getDefaultMiddleware) => | |
| getDefaultMiddleware().prepend( | |
| nextReduxCookieMiddleware({ | |
| // PERSIST AUTH SLICE IN STATE | |
| subtrees: PERSISTED_REDUCERS, | |
| }) | |
| ), | |
| }); | |
| export const appStore = store; | |
| const makeStore = wrapMakeStore(() => store); | |
| type Store = ReturnType<typeof makeStore>; | |
| export type AppDispatch = Store['dispatch']; | |
| export type RootState = ReturnType<Store['getState']>; | |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | |
| export type GetStateFromReducers<T> = T extends (...args: any[]) => infer Ret | |
| ? Ret | |
| : T extends Record<any, any> | |
| ? { | |
| [K in keyof T]: GetStateFromReducers<T[K]>; | |
| } | |
| : T; | |
| export type GlobalState = GetStateFromReducers<typeof combinedReducer>; | |
| export const wrapper = createWrapper(makeStore, { debug: false }); | |
| declare module '@reduxjs/toolkit' { | |
| type AsyncThunkConfig = { | |
| state?: unknown; | |
| dispatch?: Dispatch; | |
| extra?: unknown; | |
| rejectValue?: unknown; | |
| serializedErrorType?: unknown; | |
| }; | |
| function createAsyncThunk< | |
| Returned, | |
| ThunkArg = void, | |
| ThunkApiConfig extends AsyncThunkConfig = { | |
| // DECLARING WHAT MY getState() method returns; | |
| state: GlobalState; // this line makes a difference | |
| } | |
| >( | |
| typePrefix: string, | |
| payloadCreator: AsyncThunkPayloadCreator< | |
| Returned, | |
| ThunkArg, | |
| ThunkApiConfig | |
| >, | |
| options?: any | |
| ): AsyncThunk<Returned, ThunkArg, ThunkApiConfig>; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment