我想知道是否有人在创建服务器端渲染NodeJS应用程序时遇到问题,该应用程序在本地可完美运行,但是一旦部署到heroku,就不会加载服务器端。
我使用Jared Palmer出色的RazzleJS结合Redux,React Router和React Router Config创建了一个应用程序。
它的工作方式是在我的server.js
文件中检查正在加载的名为fetchData
的静态函数的组件,如果该函数存在,则该函数将运行,这是一个基于promise的请求到使用axios的API进行转换。
然后在我的server.js
文件中运行另一个函数,该函数在最终呈现页面的HTML之前检查所有Promise是否已完成。
在本地这可以完美地工作,即使禁用了Javascript,页面也会加载完整的数据。
已将其部署到heroku(单个dyno-业余爱好计划),但是,如果我禁用了javascript,则该页面正在加载而缺少数据,这表明该页面是在promise解决之前呈现的。然后,使用等效的ComponentDidMount分派为数据正确加载数据。
我目前有以下代码:
function handleRender(req, res) {
const sheet = new ServerStyleSheet();
const store = createStore(rootReducer, compose(applyMiddleware(thunk)));
const branch = matchRoutes(Routes, req.url);
const promises = branch.map(({ route }) => {
let fetchData = route.component.fetchData;
return fetchData instanceof Function
? fetchData(store, req.url)
: Promise.resolve(null);
});
return Promise.all(promises).then(() => {
const context = {};
const html = renderToString(
sheet.collectStyles(
<Provider store={store}>
<StaticRouter context={context} location={req.url}>
{renderRoutes(Routes)}
</StaticRouter>
</Provider>
)
);
const helmet = Helmet.renderStatic();
const styleTags = sheet.getStyleTags();
const preloadedState = store.getState();
if (context.url) {
res.redirect(context.url);
} else {
res
.status(200)
.send(renderFullPage(html, preloadedState, styleTags, helmet));
}
});
}
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchProductData } from '../thunks/product-data';
class Test extends Component {
static fetchData(store, url) {
store.dispatch(fetchProductData());
}
componentDidMount() {
if(this.props.productData.length === 0 ) {
this.props.fetchProductData() // Successfully fetches the data
}
}
render() {
return (
<div>
{ this.props.productData && this.props.productData.map( (product, i) => {
return <div key={i}>{product.title}</div>
})}
</div>
);
}
}
const mapStateToProps = state => {
return {
productData: state.productData
}
};
const mapDispatchToProps = dispatch => {
return {
fetchProductData(){
dispatch(fetchProductData());
}
}
};
export const TestContainer = connect(mapStateToProps, mapDispatchToProps)(Test);
这只是组件布局的一个示例,因为我实际拥有的组件非常复杂,但是在这种情况下,productData
在defaultState中将设置为[]
。
所有缩减工具和操作也都在本地正常工作,仅当按照一项业余计划部署到Heroku时,服务器端渲染似乎不再起作用了吗?
答案 0 :(得分:0)
因此,经过一整天的研究,之所以无法在我的实时环境中工作,是因为我具有用于跟踪分析目的的HOC包装组件。
但是,react-router-config无法处理fetchData函数是层次结构中更深一层的事实,因此我的所有诺言都用null进行了解决。
现在,我再次删除了HOC组件,服务器端渲染再次正常工作:)