Front-Complete/src/app/store/store.ts

112 lines
2.7 KiB
TypeScript

import i18n from 'app/store/i18nSlice';
import apiService from 'app/store/apiService';
import {
ReducersMapObject,
configureStore,
Store,
combineSlices,
buildCreateSlice,
asyncThunkCreator,
Middleware
} from '@reduxjs/toolkit';
import { createDynamicMiddleware } from '@reduxjs/toolkit/react';
import { AppDispatchType } from 'app/store/types';
import { useDispatch } from 'react-redux';
import { setupListeners } from '@reduxjs/toolkit/query';
import { createLogger } from 'redux-logger';
/**
* The dynamic middleware instance.
*/
const dynamicInstance = createDynamicMiddleware();
export const { middleware: dynamicMiddleware } = dynamicInstance;
export const addAppMiddleware = dynamicInstance.addMiddleware.withTypes<Config>();
const middlewares: Middleware[] = [apiService.middleware, dynamicMiddleware];
if (process.env.NODE_ENV === 'development') {
const logger = createLogger({ collapsed: (getState, action, logEntry) => (logEntry ? !logEntry.error : true) });
middlewares.push(logger);
}
/**
* The type definition for the lazy loaded slices.
*/
export interface LazyLoadedSlices {}
/**
* The static reducers.
*/
const staticReducers: ReducersMapObject = {
i18n,
[apiService.reducerPath]: apiService.reducer
};
/**
* The root reducer.
*/
export const rootReducer = combineSlices(staticReducers).withLazyLoadedSlices<LazyLoadedSlices>();
/**
* The type definition for the root state.
*/
export type RootState = ReturnType<typeof rootReducer>;
/**
* Configures the app store.
*/
export function configureAppStore(initialState?: RootState) {
const store = configureStore({
reducer: rootReducer,
preloadedState: initialState,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(middlewares)
}) as Store<RootState>;
setupListeners(store.dispatch);
return store;
}
/**
* The type definition for the app store.
*/
export type AppStore = typeof store;
/**
* The type definition for the app dispatch.
*/
export type AppDispatch = AppStore['dispatch'];
/**
* Typed hook to get the dispatch function from the Redux store.
*/
export const useAppDispatch: () => AppDispatchType = useDispatch;
/**
* Shortage for the root state selector.
*/
export const appSelector = rootReducer.selector;
/**
* createAppSlice is a wrapper around createSlice that adds support for asyncThunkCreator.
*/
export const createAppSlice = buildCreateSlice({
creators: { asyncThunk: asyncThunkCreator }
});
/**
* The type definition for the config object passed to `withAppMiddleware`.
*/
type Config = {
state: RootState;
dispatch: AppDispatch;
};
export const withAppMiddleware = dynamicInstance.withMiddleware.withTypes<Config>();
const store = configureAppStore();
export default store;