问题描述
我在打字稿中有一个用Razzle制作的服务器端渲染react应用程序。这是我想要实现的。我希望服务器在呈现我的应用程序中的任何页面之前先获取经过身份验证的数据,将其分派到商店,然后将其插入到呈现的文档中,以供客户端提取并在商店中使用。
我已经可以使用 react-router-config 和 promises 对特定路由执行调度操作,并且每个请求都是通过axios发出的。
我的商店
import { createStore,applyMiddleware,compose } from "redux";
import promiseMiddleware from "redux-promise-middleware";
import { composeWithDevTools } from "redux-devtools-extension";
import thunkMiddleware from "redux-thunk";
import reducer,{ IRootState } from "./root.reducer";
import notificationMiddleware from "config/notification-middleware";
import loggerMiddleware from "config/logger-middleware";
import loadingBarMiddleware from "config/loading-bar-middleware";
const defaultMiddlewares = [
thunkMiddleware,notificationMiddleware,promiseMiddleware,loadingBarMiddleware,loggerMiddleware,];
const composedMiddlewares = (middlewares: any) =>
process.env.NODE_ENV === "development"
? composeWithDevTools(
applyMiddleware(...defaultMiddlewares,...middlewares)
)
: compose(applyMiddleware(...defaultMiddlewares,...middlewares));
const initialize = (initialState?: IRootState,middlewares = []) => createStore(reducer,initialState,composedMiddlewares(middlewares));
export default initialize;
getSession的操作
server.ts
import renderApp from "server/renderer";
const Routes = [
{
path: "/",component: Home,loadData: (dispatch: Thunkdispatch<IRootState,void,Action<any>>) => dispatch(getSession()),},// etc.
];
// Create a new Redux store instance
const store = initStore();
const { dispatch } = store;
const actions = bindActionCreators({ clearauthentication },dispatch);
setupaxiosInterceptors(() => actions.clearauthentication("Unauthorized action"),Cookies.load("jhi-authenticationToken",req));
const routes = matchRoutes(Routes,req.path);
const promises = routes.map(({ route }: any) =>
route.loadData instanceof Function ? route.loadData(dispatch) : Promise.resolve()
);
Promise.all(promises).then(() => {
renderApp(store,req,res);
});
renderer.tsx //从我们的Redux商店中获取初始状态
import serialize from "serialize-javascript";
const finalState = store.getState();
const markup = renderToString(
<StaticRouter context={context} location={req.url}>
<Provider store={store}>
<App />
</Provider>
</StaticRouter>
)
);
res.status(200).send(`<!DOCTYPE html>
<html lang="fr">
<head>
<Meta http-equiv="X-UA-Compatible" content="IE=edge" />
<Meta charset="utf-8" />
</head>
<body>
<div id="root">${markup}</div>
<script>
window.__PRELOADED_STATE__ = ${serialize(finalState)};
</script>
</body>
</html>`
)
);
}
};
但是我的商店没有更新,并且从初始状态开始我仍然有相同的数据。
注意
- 我在浏览器中检查了呈现的HTML,这是我收到的初始状态
- 当我在reducers中插入一些console.logs并且终端上没有日志时,这些动作似乎并没有更新我的状态
- getSession 在客户端上效果很好。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)