【问题标题】:React app hosted on Heroku throw 500 Server error托管在 Heroku 上的 React 应用程序抛出 500 服务器错误
【发布时间】:2020-03-18 04:38:59
【问题描述】:

我有一个 react 应用程序,可以在我的本地 Node.JS 服务器上完美运行。但是当我尝试使用 heroku 在线托管它时,它会抛出错误,我无法访问该网站。我认为这与渲染我的一个组件有关。

Heroku CLI 错误日志:

2020-03-17T18:33:00.452210+00:00 heroku[router]: at=info method=GET path="/" host=distributed-care.herokuapp.com request_id=e6b39986-507f-4458-a126-9af86abd2006 fwd="178.221.193.75" dyno=web.1 connect=1ms service=2332ms status=500 bytes=2628 protocol=https
2020-03-17T18:40:04.350680+00:00 app[web.1]: ReferenceError: window is not defined
2020-03-17T18:40:04.350693+00:00 app[web.1]: at new setState (/app/build/static/js/components/SecondaryNav/SecondaryNav.js:32:10)
2020-03-17T18:40:04.350694+00:00 app[web.1]: at i (/app/build/static/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:606:24)
2020-03-17T18:40:04.350695+00:00 app[web.1]: at isValidElement (/app/build/static/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:655:12)
2020-03-17T18:40:04.350696+00:00 app[web.1]: at e.render (/app/build/static/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:811:44)
2020-03-17T18:40:04.350697+00:00 app[web.1]: at e.suspenseDepth [as read] (/app/build/static/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:784:18)
2020-03-17T18:40:04.350697+00:00 app[web.1]: at Object.renderToString (/app/build/static/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:668:10)
2020-03-17T18:40:04.350698+00:00 app[web.1]: at routeConfiguration (/app/build/static/js/index.js:113:27)
2020-03-17T18:40:04.350699+00:00 app[web.1]: at Object.exports.render (/app/server/renderer.js:95:26)
2020-03-17T18:40:04.350699+00:00 app[web.1]: at /app/server/index.js:201:29
2020-03-17T18:40:04.350700+00:00 app[web.1]: at processTicksAndRejections (internal/process/task_queues.js:97:5)
2020-03-17T18:40:04.350848+00:00 app[web.1]: server-side-render-failed
2020-03-17T18:40:04.350970+00:00 app[web.1]: undefined

所以我尝试在没有 SecondaryNav 组件的情况下在线运行服务器,并且它可以工作,所以 SecondaryNav 出现问题。

SecondaryNav.js

import React, { Component } from "react";
import classnames from "classnames";
import css from './SecondaryNav.css';

export default class SecondaryNav extends Component {
  constructor(props) {
    super(props);

    this.state = {
      prevScrollpos: window.pageYOffset,
      visible: true
    };
  }

  // Adds an event listener when the component is mount.
  componentDidMount() {
    window.addEventListener("scroll", this.handleScroll);
  }

  // Remove the event listener when the component is unmount.
  componentWillUnmount() {
    window.removeEventListener("scroll", this.handleScroll);
  }

  // Hide or show the menu.
  handleScroll = () => {
    const { prevScrollpos } = this.state;

    const currentScrollPos = window.pageYOffset;
    const visible = prevScrollpos > currentScrollPos;

    this.setState({
      prevScrollpos: currentScrollPos,
      visible
    });
  };

  render() {
    return (
      <div className={classnames(css.navbar, css.secondaryMenu, {
        [css.navbarHidden] : !this.state.visible
        })}>      
        <ul>
          <li><span>Senior Care</span></li>
          <li><span>Elderly</span></li>
          <li><span>In-home Care</span></li>
          <li><span>Look After</span></li>
          <li><span>Verified</span></li>
          <li><span>See All Categories</span></li>
        </ul>
      </div>
    );
  }
}

SecondaryNav.css

@import '../../marketplace.css';

.navbar {
    height: 40px;
    transition: height .35s ease-out;
  }

  .navbarHidden {
    height: 0;
  }

  .secondaryMenu {
    margin: 0 auto;
    box-shadow: 0 1px 6px rgba(57,73,76,.35);

    @media (max-width: 1170px) {
      display: none !important;
    }

    @media (--viewportLarge) {
        position: absolute;
        left: 0;
        right: 0;
        margin: auto;
        background-color: #0095b3;
        box-shadow: -900px 0 0 #f9f9f9, -900px -1px 0 #e0e0e0, 900px 0 0 #f9f9f9, 900px -1px 0 #e0e0e0, 0 -1px 0 #e0e0e0;
        overflow: hidden;
    }
  }

  .secondaryMenu ul {
    width: 1170px;
    padding: 0 24px;
    display: flex;
    justify-content: space-between;
    list-style: none;
    overflow: hidden;
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;

  }

  .secondaryMenu ul li {
    display: flex;
    align-items: center;
    padding: 0 0 2px;
    color: #fff;
  }

  .secondaryMenu ul li:hover {
    cursor: pointer;
  }

  .secondaryMenu ul li span {
    font-size: 16px;
    font-weight: 300;
  }

我做错了什么,无论如何我可以解决这个问题吗?正如我所说,它在我的本地服务器上完美运行,但在 heroku 上抛出错误。如果有人能告诉我是什么导致了这个问题,我也会感激不尽。

问候!

【问题讨论】:

    标签: node.js reactjs heroku


    【解决方案1】:

    我找到了导致问题的原因。这是因为服务器无法渲染 SecondaryNav 文件,因为它使用的是 jQuery 函数。所以窗口是一个全局变量,它不包含在文件中。

    固定文件:

    import React, { Component } from "react";
    import classnames from "classnames";
    import css from './SecondaryNav.css';
    
    const hasWindow = (typeof window !== 'undefined') ? true : false;
    
    export default class SecondaryNav extends Component {
      constructor(props) {
        super(props);
    
        this.state = {
          prevScrollpos: hasWindow ? window.pageYOffset : null,
          visible: true
        };
      }
    
      // Adds an event listener when the component is mount.
      componentDidMount() {
        if (hasWindow == true) {
          window.addEventListener("scroll", this.handleScroll);
        }
      }
    
      // Remove the event listener when the component is unmount.
      componentWillUnmount() {
        if (hasWindow == true) {
          window.removeEventListener("scroll", this.handleScroll);
        }
      }
    
      // Hide or show the menu.
      handleScroll = () => {
        const { prevScrollpos } = this.state;
    
        const currentScrollPos = hasWindow ? window.pageYOffset : null;
        const visible = prevScrollpos > currentScrollPos;
    
        this.setState({
          prevScrollpos: currentScrollPos,
          visible
        });
      };
    
      render() {
        return (
          <div className={classnames(css.navbar, css.secondaryMenu, {
            [css.navbarHidden] : !this.state.visible
            })}>      
            <ul>
              <li><span>Senior Care</span></li>
              <li><span>Elderly</span></li>
              <li><span>In-home Care</span></li>
              <li><span>Look After</span></li>
              <li><span>Verified</span></li>
              <li><span>See All Categories</span></li>
            </ul>
          </div>
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-11-21
      • 2011-03-05
      • 2016-02-08
      • 1970-01-01
      • 2017-10-20
      • 2021-08-01
      • 2012-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多