首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在服务器端输出空字符串的反应头盔

在服务器端输出空字符串的反应头盔
EN

Stack Overflow用户
提问于 2017-08-23 00:35:23
回答 1查看 2.8K关注 0票数 3

我正在使用react-helmet,在客户机上,inspect窗口中的所有内容都是正常的,并且标签正在正确输出。但是,当我在生产环境中启动时,SSR启动时,标签不会显示在源代码中,也不会出现任何错误。

我也尝试了记录“stringified”标题标签,得到了:

代码语言:javascript
复制
<title data-react-helmet="true"></title>

下面是一些代码:

这是我设置标签的页面组件之一,3个页面组件的设置都与此相同。(我已经简化了组件、呈现函数和数据对象,因为它们非常大,我确信它们不会出错。)

代码语言:javascript
复制
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { Helmet } from 'react-helmet';

// Components
import WorkGrid from 'universal/components/Grid';
import Wrapper from 'universal/components/Wrapper';
import Container from 'universal/components/Container';
import Hero from 'universal/components/Hero';
import PageWrapper from 'universal/components/PageWrapper';
import GridHeader from 'universal/components/GridHeader';

const data = {};

class Work extends PageComponent {

  render () {
    return (
      <PageWrapper ref="root">
        <Helmet>
          <title>Work</title>
          <meta name="description" content="Work Description" />
        </Helmet>
        <h1>Work Page</h1>
      </PageWrapper>
    );
  }
}

export default connect(state => ({
  theme: state.ui.theme
}), { changeTheme }, null, { withRef: true })(Work);

这是一些服务器代码,特别是在SSR发生故障的地方,我调用了Helmet.renderStatic();

代码语言:javascript
复制
    // Node Modules
import fs from 'fs';
import {basename, join} from 'path';

// Libraries
import React from 'react';
import {StaticRouter} from 'react-router';
import {renderToString} from 'react-dom/server';

// styled-components
import { ServerStyleSheet, ThemeProvider } from 'styled-components';
import { theme } from '../universal/constants';

// Redux
// import {push} from 'react-router-redux';
import createStore from 'data/redux/createStore.js';
import createHistory from 'history/createMemoryHistory';
import { Provider } from 'react-redux';

// Third Party Scripts
import * as thirdPartyScripts from './thirdPartyScripts.js';

// Helmet
import {Helmet} from 'react-helmet';

function renderApp(url, res, store, assets) {
  const PROD = process.env.NODE_ENV === 'production';
  const context = {};

  const {
    manifest,
    app,
    vendor
  } = assets || {};

  let state = store.getState();

  const stylesheet = new ServerStyleSheet();

  const initialState = `window.__INITIAL_STATE__ = ${JSON.stringify(state)}`;
  const Layout =  PROD ? require( '../../build/prerender.js') : () => {};

  const root = PROD && renderToString(
    stylesheet.collectStyles(
      <Provider store={store}>
        <ThemeProvider theme={theme}>
          <StaticRouter location={url} context={context}>
            <Layout />
          </StaticRouter>
        </ThemeProvider>
      </Provider>
    )
  );

  const styleTags = stylesheet.getStyleTags();

  const seo = Helmet.renderStatic();

  console.log(seo.title.toString());

  const html = `<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        ${seo.title.toString()}
        ${seo.meta.toString()}
        ${seo.link.toString()}

        <link rel="shortcut icon" href="/favicon.ico">
        <link rel="icon" sizes="16x16 32x32 64x64" href="/favicon.ico">
        <link rel="apple-touch-icon" href="/favicon-57.png">
        <link rel="apple-touch-icon" sizes="114x114" href="/favicon-114.png">
        <link rel="apple-touch-icon" sizes="72x72" href="/favicon-72.png">
        <link rel="apple-touch-icon" sizes="144x144" href="/favicon-144.png">
        <link rel="apple-touch-icon" sizes="60x60" href="/favicon-60.png">
        <link rel="apple-touch-icon" sizes="120x120" href="/favicon-120.png">
        <link rel="apple-touch-icon" sizes="76x76" href="/favicon-76.png">
        <link rel="apple-touch-icon" sizes="152x152" href="/favicon-152.png">
        <link rel="apple-touch-icon" sizes="180x180" href="/favicon-180.png">
        <meta name="msapplication-TileColor" content="#FFFFFF">
        <meta name="msapplication-TileImage" content="/favicon-144.png">
        <meta name="msapplication-config" content="/browserconfig.xml">

        ${ styleTags }

        ${PROD ? '<link rel="stylesheet" href="/static/prerender.css" type="text/css" />' : ''}

        <link href="${thirdPartyScripts.googleFont}" rel="stylesheet" type="text/css">

        <script>${thirdPartyScripts.googleAnalytics}</script>
    </head>

    <body>
      <script>${initialState}</script>
      ${PROD ? `<div id="root">${root}</div>` : '<div id="root"></div>'}

      ${PROD ? `<script>${manifest.text}</script>` : ''}

      <script>${thirdPartyScripts.facebookPixel}</script>

      <script async src="${thirdPartyScripts.googleAnalyticsSrc}"></script>
      ${PROD ? `<script src="${vendor.js}"></script>` : ''}
      <script src="${PROD ? app.js : './static/app.js'}"></script>
    </body>
    </html>`;

  res.send(html);
}

另外,如果有任何帮助的话,我正在使用React Router v4。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-08 23:24:11

前几周我找到了这个问题的解决方案,我想我也可以更新这篇文章,这样它就可以帮助任何有这个问题的人……

好消息是它出奇的简单!

无论如何,对我来说,这是因为我将客户端和服务器端的webpack包分开了。因此,用外行的话来说,它包含了react-helmet两次,一次用于客户端,一次用于服务器,这意味着在客户端代码中保存元标记的所有状态在服务器上的.rewind()调用中都不存在。

只需将此文件添加到您的服务器webpack配置文件中

externals: ['react-helmet']

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45822925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档