我正在为我的应用程序使用react-boilerplate(使用 SSR 分支)。出于某种原因,我们需要服务器端渲染。此外,我们还有一些其他 API,我们需要在所有 API 之前调用一个 API(用于注册某些内容)。我认为对于初始状态,我需要在服务器上调用这个(第一个需要注册数据的 API)API 并将响应数据保存到存储中并将存储返回给客户端。在创建商店的反应样板中:
/**
* Create the store with asynchronously loaded reducers
*/
import { createStore, applyMiddleware, compose } from 'redux';
import { fromJS } from 'immutable';
import { routerMiddleware } from 'react-router-redux';
import createSagaMiddleware from 'redux-saga';
import createReducer from './reducers';
const sagaMiddleware = createSagaMiddleware();
export default function configureStore(initialState = {}, history) {
// Create the store with two middlewares
// 1. sagaMiddleware: Makes redux-sagas work
// 2. routerMiddleware: Syncs the location/URL path to the state
const middlewares = [
sagaMiddleware,
routerMiddleware(history),
];
const enhancers = [
applyMiddleware(...middlewares),
];
// If Redux DevTools Extension is installed use it, otherwise use Redux compose
/* eslint-disable no-underscore-dangle */
const composeEnhancers =
process.env.NODE_ENV !== 'production' &&
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose;
/* eslint-enable */
const store = createStore(
createReducer(),
fromJS(initialState),
composeEnhancers(...enhancers)
);
// Extensions
store.runSaga = sagaMiddleware.run;
store.asyncReducers = {}; // Async reducer registry
// Make reducers hot reloadable, see http://mxs.is/googmo
/* istanbul ignore next */
if (module.hot) {
module.hot.accept('./reducers', () => {
import('./reducers').then((reducerModule) => {
const createReducers = reducerModule.default;
const nextReducers = createReducers(store.asyncReducers);
store.replaceReducer(nextReducers);
});
});
}
return store;
}
并且还用于定义初始商店:
function renderAppToStringAtLocation(url, { webpackDllNames = [], assets, lang }, callback) {
const memHistory = createMemoryHistory(url);
const store = createStore({}, memHistory);
syncHistoryWithStore(memHistory, store);
const routes = createRoutes(store);
const sagasDone = monitorSagas(store);
store.dispatch(changeLocale(lang));
match({ routes, location: url }, (error, redirectLocation, renderProps) => {
if (error) {
callback({ error });
} else if (redirectLocation) {
callback({ redirectLocation: redirectLocation.pathname + redirectLocation.search });
} else if (renderProps) {
renderHtmlDocument({ store, renderProps, sagasDone, assets, webpackDllNames })
.then((html) => {
const notFound = is404(renderProps.routes);
callback({ html, notFound });
})
.catch((e) => callback({ error: e }));
} else {
callback({ error: new Error('Unknown error') });
}
});
}
为了填充初始状态,我做了一些改变:
async function fetches (hostname) {
const domain = hostname.replace('.myExample.com', '').replace('www.', '');
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/example.api.v1.0+json',
}
};
const uri ='https://api.example.com/x/' + domain + '/details';
const shopDetail = await fetch(uri, options);
return shopDetail.json();
}
function renderAppToStringAtLocation(hostname ,url, { webpackDllNames = [], assets, lang }, callback) {
const memHistory = createMemoryHistory(url);
console.log('url :', hostname);
fetches(hostname).then( data => {
const store = createStore(data, memHistory);
syncHistoryWithStore(memHistory, store);
const routes = createRoutes(store);
const sagasDone = monitorSagas(store);
store.dispatch(changeLocale(lang));
match({ routes, location: url }, (error, redirectLocation, renderProps) => {
if (error) {
callback({ error });
} else if (redirectLocation) {
callback({ redirectLocation: redirectLocation.pathname + redirectLocation.search });
} else if (renderProps) {
renderHtmlDocument({ store, renderProps, sagasDone, assets, webpackDllNames })
.then((html) => {
const notFound = is404(renderProps.routes);
callback({ html, notFound });
})
.catch((e) => callback({ error: e }));
} else {
callback({ error: new Error('Unknown error') });
}
});
});
然后在控制台中我收到此错误:
Unexpected properties "code", "data" found in initialState argument
passed to createStore. Expected to find one of the known reducer
property names instead: "route", "global", "language". Unexpected
properties will be ignored.
如何解决?