diff --git a/.changeset/forty-files-help.md b/.changeset/forty-files-help.md new file mode 100644 index 00000000..f26e645e --- /dev/null +++ b/.changeset/forty-files-help.md @@ -0,0 +1,5 @@ +--- +'@modern-js-reduck/store': patch +--- + +fix: fix initial state missing diff --git a/packages/store/src/store/createStore.ts b/packages/store/src/store/createStore.ts index 4a356abb..e38eb90b 100644 --- a/packages/store/src/store/createStore.ts +++ b/packages/store/src/store/createStore.ts @@ -2,8 +2,10 @@ import { applyMiddleware, compose, createStore as createReduxStore, - Reducer, - StoreEnhancerStoreCreator, + type Action, + type Reducer, + type StoreEnhancer, + type StoreEnhancerStoreCreator, } from 'redux'; import { createContext } from './context'; import type { Context, StoreConfig } from '@/types'; @@ -31,6 +33,7 @@ const createStore = (props: StoreConfig = {}): Context['store'] => { initialState, compose>( ...[ + mergeInitialState(), middlewares ? applyMiddleware(...middlewares) : undefined, ...(enhancers || []), ].filter(Boolean), @@ -50,4 +53,36 @@ const createStore = (props: StoreConfig = {}): Context['store'] => { return store; }; +/** + * Merge prev global state when mounting new models + * to avoid to miss the initial state of the mounting models + */ +function mergeInitialState(): StoreEnhancer { + return createStore => (reducer, initialState) => { + const liftReducer = (r: Reducer) => { + if (typeof r !== 'function') { + throw new Error('Expected the reducer to be a function.'); + } + + return (state = initialState, action: Action) => { + const nextState = r(state, action); + if (/^@@redux\/REPLACE/.test(action.type)) { + return { ...state, ...nextState }; + } else { + return nextState; + } + }; + }; + + const store = createStore(liftReducer(reducer)); + + return { + ...store, + replaceReducer: reducer => { + return store.replaceReducer(liftReducer(reducer)); + }, + }; + }; +} + export default createStore;