Skip to content

Instantly share code, notes, and snippets.

@javonmcgilberry
Created April 26, 2022 04:57
Show Gist options
  • Select an option

  • Save javonmcgilberry/dc4d18fccc0cafaeeb9c1b292a14beb5 to your computer and use it in GitHub Desktop.

Select an option

Save javonmcgilberry/dc4d18fccc0cafaeeb9c1b292a14beb5 to your computer and use it in GitHub Desktop.
Redux Store Starter with Next Redux Wrapper
/* 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