2017-08-22 32 views
2

我正在使用反應頭盔,並且在客戶端上所有在檢查窗口中都很好,並且正在正確輸出標籤。但是,當我在生產環境中啓動時,源代碼中未顯示標記中的SSR啓動,並且我沒有收到任何錯誤。反應頭盔在服務器端輸出空字符串

我試圖登錄的「字符串化」的標題標籤也找來:

<title data-react-helmet="true"></title> 

下面是一些代碼:

這是我自定的標籤頁面組件之一, 3個頁面組件的設置完全相同。 (我已經簡化了組件渲染功能和數據對象,因爲它們是相當大的,我敢肯定,這些都沒有錯。)

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

// 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,如果有任何幫助的話。

回答

0

我找到了解決這個一週,我想我可能也更新此所以它可以幫助其他人有這個問題...

好消息是這是令人驚訝的簡單!

對我來說,無論如何,這是事實,我分開的客戶端和服務器的webpack包。所以通俗地說,它包括兩次反應頭盔,一次爲客戶端,一次爲服務器,意味着在客戶端代碼中保存元標記的所有狀態都不存在於服務器上的.rewind()調用中。

只需添加到您的服務器的WebPack配置文件

externals: ['react-helmet']

相關問題