繁体   English   中英

NodeJS服务器端在本地工作,但不在Heroku上工作

[英]NodeJS Server Side working Locally but not on Heroku

我想知道是否有人在创建服务器端渲染NodeJS应用程序时遇到问题,该应用程序在本地可以完美运行,但是一旦部署到heroku后就不会加载服务器端。

我使用Jared Palmer的超棒RazzleJS结合Redux,React Router和React Router Config创建了一个应用程序。

它的工作方式是,在我的server.js文件中,我检查了正在加载的组件中是否有一个名为fetchData的静态函数,如果该函数存在,则该函数将运行,这是基于thunk的axios对API的基于承诺的请求。

在我的server.js文件中,然后运行另一个函数,该函数在最终呈现页面的HTML之前检查所有Promise是否已完成。

在本地这是完美的,即使禁用了Javascript,页面也会加载完整的数据。

已经将其部署到heroku(单个dyno-业余爱好计划),但是,如果我禁用了javascript,页面正在加载而数据丢失,这表明该页面在promise解决之前就已呈现。 然后,使用等效的ComponentDidMount分派为数据正确加载数据。

我目前有以下代码:

Server.js

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));
    }
  });
}

示例React组件

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中设置为[]

同样,所有的reducer和action在本地都无法正常工作,只是只有按照业余计划将其部署到Heroku时,服务器端渲染才似乎不再起作用?

因此,经过一整天的研究,之所以无法在我的实时环境中工作,是因为我有一个用于跟踪分析的HOC包装组件。

但是React-router-config无法处理fetchData函数是层次结构中更深一层的事实,因此我的所有诺言都用null进行了解析。

现在,我再次删除了HOC组件,服务器端渲染再次正常工作:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM