对不起,英语不好。
我在用ssr(pure react)+ redux +代码拆分(@loadable)+注入redux挣扎。 (受反应样板的影响很大)
当前,我的代码在没有预加载数据的情况下运行良好。
我不知道在注入reducer之前如何处理ssr预加载数据。
下面是帮助解决我的问题的示例。
store = {
global: { // default
key: 'value' // this is done. ssr working great using this value.
},
injected: { // dynamically injected. using replaceReducer per page. (same with react-boilerplate)
key: 'value' // I want to put this value on ssr preload. (not working)
}
}
说完了
Unexpected property "injected" found in previous state received by the reducer. Expected to find one of the known reducer property names instead: "global". Unexpected properties will be ignored.
我知道为什么会出现此错误(因为初始存储没有“已注入”存储。),但我不知道如何正确修复它。
有没有用法示例?
这是我的想法,但这似乎不是正确的答案。
答案 0 :(得分:0)
reducerInjector.js
export const injectState = (reducers, preloadedState = {}) =>
Object.keys(reducers).reduce((result, key) => {
const finalReducers = result;
if (typeof reducers[key] === 'function') {
finalReducers[key] = (state = preloadedState[key], action) => reducers[key](state, action);
}
return finalReducers;
}, {});
export const createInitialState = (reducers, preloadedState = {}) =>
Object.keys(preloadedState).reduce((r, key) => {
if (!reducers[key]) return r;
return { ...r, [key]: preloadedState[key] };
}, {});
export const createReducer = (staticReducers, asyncReducers, preloadedState) =>
combineReducers(injectState({
...staticReducers,
...asyncReducers,
}, preloadedState));
export default function reducerInjector(store, staticReducers, preloadedState) {
// Add a dictionary to keep track of the registered async reducers
store.asyncReducers = {};
// Create an inject reducer function
// This function adds the async reducer, and creates a new combined reducer
store.injectReducer = (key, asyncReducer) => {
store.asyncReducers[key] = asyncReducer;
store.replaceReducer(createReducer(staticReducers, store.asyncReducers, preloadedState));
};
return store;
}
...
import reducerInjector, { createReducer, createInitialState } from './reducerInjector';
const configureStore = (initialState, ssr) => {
const sagaMiddleware = createSagaMiddleware({});
const createStoreWithMiddleware = compose(applyMiddleware(thunkMiddleware, sagaMiddleware));
const reducer = createReducer(rootReducer, {}, initialState);
const initialData = createInitialState(rootReducer, initialState);
let store = createStoreWithMiddleware(createStore)(reducer, initialData);
store = reducerInjector(store, rootReducer, initialState);
return store;
}