簡體   English   中英

文本內容不匹配。 React 16 中的警告

[英]Text content did not match. Warning in React 16

我嘗試使用服務器端渲染構建 ReactJs 應用程序我的客戶端和服務器入口點:

客戶端.jsx

const store = createStore(window.__INITIAL_STATE__);

hydrate(
  <Provider store={store}>
    <BrowserRouter>{renderRoutes(routes)}</BrowserRouter>
  </Provider>,
  document.querySelector('#root')
);

服務器.jsx

const app = express();

if (isDev) {
  const webpack = require('webpack');
  const webpackDevMiddleware = require('webpack-dev-middleware');
  const config = require('../../webpack.config.js');
  const compiler = webpack(config);

  app.use(express.static('/public'));
  app.use(
    webpackDevMiddleware(compiler, {
      publicPath: config.output.publicPath,
      stats: 'errors-only',
    })
  );
}

app.get('*', (req, res) => {
  const helmet = Helmet.renderStatic();
  const htmlAttrs = helmet.htmlAttributes.toComponent();
  const bodyAttrs = helmet.bodyAttributes.toComponent();

  const context = {};
  const data = {};

  res.set('content-type', 'text/html');

  res.send(
    '<!DOCTYPE html>' +
      renderToString(
        <html {...htmlAttrs}>
          <head>
            {helmet.title.toComponent()}
            {helmet.meta.toComponent()}
            {helmet.link.toComponent()}
          </head>
          <body {...bodyAttrs}>
            <div id="root">
              <StaticRouter location={req.url} context={context}>
                {renderRoutes(routes)}
              </StaticRouter>
            </div>
            <script
              dangerouslySetInnerHTML={{
                __html: `window.__INITIAL_STATE__ = ${JSON.stringify(data)}`,
              }}
            />
            <script src="/public/vendor.js" />
            <script src="/public/app.js" />
          </body>
        </html>
      )
  );
});

和組件:

主頁.jsx

import React, { Component } from 'react';

class Home extends Component {
  render() {
    return <div>home</div>;
  }
}

export default Home;

當我更改我的組件Home並刷新瀏覽器頁面時,我收到此錯誤:

警告:文本內容不匹配。 服務器:“home” 客戶端:“home1”

沒關系,因為服務器呈現我的代碼的舊版本。 如何在服務器上重新加載代碼,使客戶端和服務器版本相等?

對於那些因為您的客戶端和服務器故意呈現不同內容而發現此錯誤的人(例如,服務器呈現一個黑暗主題,該主題在加載時被用戶首選項替換),請使用suppressHydrationWarning來抑制錯誤。

例如:

<div suppressHydrationWarning>Ignore this</div>

這里的問題是您的服務器端應用程序不反映代碼更改。 為此,您必須將 express 應用程序配置為 webpack 條目。

簡而言之,您需要 2 個 webpack 配置,一個用於服務器,另一個用於客戶端代碼。 服務器一看起來像這樣

module.exports = {
  entry: {
    server: './server.js',
  },
  output: {
    path: path.join(__dirname, 'dist'),
    publicPath: '/',
    filename: '[name].js'
  },
  target: 'node',
  node: {
    // Need this when working with express, otherwise the build fails
    __dirname: false,   // if you don't put this is, __dirname
    __filename: false,  // and __filename return blank or /
  },
  externals: [nodeExternals()], // Need this to avoid error when working with Express
  module: {
    rules: [
      {
        // Transpiles ES6-8 into ES5
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        // Loads the javacript into html template provided.
        // Entry point is set below in HtmlWebPackPlugin in Plugins 
        test: /\.html$/,
        use: [{loader: "html-loader"}]
      }
    ]
  },
  plugins: [
    new HtmlWebPackPlugin({
      template: "./index.html",
      filename: "./index.html",
      excludeChunks: [ 'server' ]
    })
  ]
}

這是一篇很好的文章,詳細解釋了如何做到這一點

沒有人說過,但是當您在優化中啟用 Auto Minify (HTML) 時,Cloudflare 用空格替換了雙空格。 並且會發生此錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM