Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React服务器端呈现呈现不正确的内容_Javascript_Reactjs_Redux_React Router_Server Side Rendering - Fatal编程技术网

Javascript React服务器端呈现呈现不正确的内容

Javascript React服务器端呈现呈现不正确的内容,javascript,reactjs,redux,react-router,server-side-rendering,Javascript,Reactjs,Redux,React Router,Server Side Rendering,我正在使用react、Redux和react路由器开发react web应用程序,并使用服务器端渲染(使用express) 我面临的问题有点难以解释。我将尝试在以下步骤中解释它 您首先从URL(如)输入应用程序。express服务器将发送正确的内容,其中包括正确的页面源和DOM(来自chrome元素面板)作为初始加载 然后,让我们导航到另一个页面,例如(导航不会导致页面刷新,因为它是一个单页应用程序,当您使用浏览器进行刷新或从浏览器地址栏中的URL输入页面时,它仅向服务器提供SSR内容)到目前为

我正在使用react、Redux和react路由器开发react web应用程序,并使用服务器端渲染(使用express)

我面临的问题有点难以解释。我将尝试在以下步骤中解释它

  • 您首先从URL(如)输入应用程序。express服务器将发送正确的内容,其中包括正确的页面源和DOM(来自chrome元素面板)作为初始加载

  • 然后,让我们导航到另一个页面,例如(导航不会导致页面刷新,因为它是一个单页应用程序,当您使用浏览器进行刷新或从浏览器地址栏中的URL输入页面时,它仅向服务器提供SSR内容)到目前为止一切正常

  • 使用cmd+r或F5在浏览器中刷新页面(您现在处于第页)。同样,服务器将发送内容。但是这次你收到的内容有点不同。浏览器中的页面内容是正确的,并且来自chrome元素面板的DOM也是正确的。但是,页面源不正确,它仍然是从步骤1获得的旧页面源

  • 我尝试在刷新页面时注销内容。服务器在步骤3中发送的内容不是正确的内容(它是上一页),但是浏览器仍然可以看到正确的内容

    如果我在第3步之后再次刷新页面,那么我将获得正确的内容和正确的页面源

    我也在使用Facebook开放图形调试器。调试器告诉我它遵循重定向到步骤3。它后面的重定向URL是上一页的URL。我知道这不太正确,但不确定我哪里做错了

    以下是我的express服务器设置

    谢谢你的帮助

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

    我最终解决了这个问题

    主要问题是我将异步数据获取调用放在
    componentWillMount
    生命周期方法中,而不是
    componentDidMount

    我没有在我的应用程序中正确处理异步数据获取

    我现在使用中提到的方法来处理异步数据获取问题

    基本上,我正在做以下工作:

  • 在客户端:在组件中创建静态方法
    fetchData

  • 在服务器端:使用React Router获取正确的组件,并使用
    fetchData
    方法获取该组件所需的数据

  • 解决这些承诺后,从Redux存储中获取当前状态,呈现HTML并将其发送到客户端

  • 将状态注入客户端Redux存储并呈现页面