我使用React,Redux和React路由器处理反应式网络应用程序,使用服务器端呈现(使用快速)
我面临的问题有点难以解释。我将尝试按以下步骤解释它。
您首先从http://www.example.com/articles/1234这样的网址输入应用。快递服务器将向下发送包含正确页面源和DOM(来自chrome Element面板)的正确内容作为初始加载。
然后让我们导航到不同的页面,例如http://www.example.com/articles/5678(导航不会导致页面刷新,因为它是单页应用程序,它只会向服务器提供SSR内容当您使用浏览器刷新或从浏览器地址栏中的URL输入页面时)到目前为止一切正常。
使用cmd + r或F5在浏览器中刷新页面(您现在在页面http://www.example.com/articles/5678上)。同样,服务器将发送内容。但这次你收到的内容有点不同。浏览器中的页面内容以及chrome Elements面板中的DOM都是正确的。但是,页面来源不正确,它仍然是您从第1步获得的旧页面来源。
我在刷新页面时尝试注销内容。服务器在步骤3中发送的内容不是正确的内容(它是上一页),但浏览器仍然可以看到正确的内容。
如果我在第3步之后再次刷新页面,那么我将获得正确的内容和正确的页面源...
我也使用Facebook开放图调试器。调试器告诉我它遵循重定向到第3步。它遵循的重定向URL是上一页URL。我知道这不太对,但不确定我做错了...
以下是我的快速服务器设置
感谢您的帮助!
server.js
require('babel-register');
const express = require('express');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const ReactRouter = require('react-router');
const ReactRedux = require('react-redux');
const Store = require('./src/store/configureStore').default;
const routes = require('./src/routes').default;
const compression = require('compression');
const morgan = require('morgan');
const store = Store();
const match = ReactRouter.match;
const RouterContext = ReactRouter.RouterContext;
const Provider = ReactRedux.Provider;
const port = process.env.PORT || 5050;
const ReactHelmet = require('react-helmet');
const Helmet = ReactHelmet.Helmet;
const app = express();
app.use('/dist', express.static('./dist'));
app.set('view engine', 'ejs');
app.use(compression());
app.use(morgan('combined'));
app.use((req, res) => {
// prettier-ignore
match(
{ routes, location: req.url },
(error, redirectLocation, renderProps) => {
if (error) {
res.status(500).send(error.message);
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
console.log(renderProps);
const body = ReactDOMServer.renderToString(
React.createElement(
Provider,
{ store },
React.createElement(RouterContext, renderProps)
)
);
const meta = Helmet.renderStatic().meta.toString();
res.status(200).render('index', {body, meta});
} else {
res.status(404).send('Not found');
}
}
);
});
console.log('listening on port ' + port); // eslint-disable-line
app.listen(port);
答案 0 :(得分:0)
我最终解决了这个问题。
主要问题是我在componentWillMount
生命周期方法而不是componentDidMount
中放置了异步数据提取调用。
我没有在我的应用程序中正确处理异步数据提取。
我现在正在使用this article中提到的方法来处理我的异步数据提取问题。
基本上,我正在做以下事情:
在客户端:在组件中创建静态方法fetchData
。
在服务器端:使用React Router获取正确的组件,并使用fetchData
方法获取该组件所需的数据。
解决了这些承诺后,从Redux商店获取当前状态并呈现HTML并将其发送给客户端。
将状态注入客户端Redux商店并呈现页面。