Javascript 反应校验和无效服务器呈现

Javascript 反应校验和无效服务器呈现,javascript,reactjs,Javascript,Reactjs,在我的react应用程序中,我当前正在使用服务器端渲染。我当前遇到的错误是: Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was e

在我的react应用程序中,我当前正在使用服务器端渲染。我当前遇到的错误是:

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
 (client) <noscript data-reacti
 (server) <div data-reactid=".1
警告:React试图重用容器中的标记,但校验和无效。这通常意味着您正在使用服务器呈现,并且在服务器上生成的标记不是客户机所期望的。React注入了新的标记以补偿其效果,但您已经失去了服务器呈现的许多好处。相反,请找出在客户端或服务器上生成的标记不同的原因:

(客户端)此问题与异步路由有关。除了将所有路由更改为同步之外,我没有找到其他解决方案。加载异步路由时,客户端添加的
标记将放置在那里

例如,更改:

const路由={
路径:“/”,
getComponent:函数(位置,cb){
要求。确保([],功能(要求){
返回cb(null,require('./视图/主页'));
})
};
};
为此:

const路由={
路径:“/”,
getComponent:函数(位置,cb){
返回cb(null,require('./视图/主页'));
};
};
编辑:要重新启用异步路由,请在客户端路由器中执行此操作:

match({history,routes},(错误,重定向位置,renderProps)=>{
渲染(,mountNode)
})

答案编辑感谢@firasd这里:

我不相信我的答案能解决这个问题。添加另一个
div
只会使消息消失。如果您以慢动作观看页面加载,它将显示服务器端,然后变为白色,然后在客户端加载,就像您收到错误一样。我对这个问题的描述和你的一样,所以我们都在使用的一些插件在那里添加了一个标记,因为我没有这样做,而你也没有。看起来这实际上是由react路由器中的异步路由引起的。目前我唯一的解决办法是删除它们。当我得到一个真正的解决方案时,我将提交一个bug并正确地更新我的答案。
 import 'babel-polyfill';
 import path from 'path';
 import express from 'express';
 import React from 'react';
 import ReactDOM from 'react-dom/server';
 import { match, RouterContext } from 'react-router';
 import assets from './assets';
 import { port } from './config';
 import routes from './routes';
 import ContextHolder from './core/ContextHolder';
 import Html from './components/Html';

 const server = global.server = express();

 //
 // Register Node.js middleware
 // -----------------------------------------------------------------------------
 server.use(express.static(path.join(__dirname, 'public')));

 //
 // Register API middleware
 // -----------------------------------------------------------------------------
 server.use('/api/content', require('./api/content').default);

 //
 // Register server-side rendering middleware
 // -----------------------------------------------------------------------------
 server.get('*', async (req, res, next) => {
   try {
     match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
       if (error) {
         throw error;
       }
       if (redirectLocation) {
         const redirectPath = `${ redirectLocation.pathname }${ redirectLocation.search }`;
         res.redirect(302, redirectPath);
         return;
       }
       let statusCode = 200;
       const data = { title: '', description: '', css: '', body: '', entry: assets.main.js };
       const css = [];
       const context = {
         insertCss: styles => css.push(styles._getCss()),
         onSetTitle: value => data.title = value,
         onSetMeta: (key, value) => data[key] = value,
         onPageNotFound: () => statusCode = 404,
       };
       data.body = ReactDOM.renderToString(
         <ContextHolder context={context}>
           <RouterContext {...renderProps}/>
         </ContextHolder>
       );
       data.css = css.join('');
       const html = ReactDOM.renderToStaticMarkup(<Html {...data} />);
       res.status(statusCode).send(`<!doctype html>\n${html}`);
     });
   } catch (err) {
     next(err);
   }
 });

 //
 // Launch the server
 // -----------------------------------------------------------------------------
 server.listen(port, () => {
   /* eslint-disable no-console */
   console.log(`The server is running at http://localhost:${port}/`);
 });
import 'babel-polyfill';
import React from 'react';
import { match, Router } from 'react-router';
import { render } from 'react-dom';
import FastClick from 'fastclick';
import routes from './routes';
import Location from './core/Location';
import ContextHolder from './core/ContextHolder';
import { addEventListener, removeEventListener } from './core/DOMUtils';

let cssContainer = document.getElementById('css');
const appContainer = document.getElementById('app');
const context = {
  insertCss: styles => styles._insertCss(),
  onSetTitle: value => document.title = value,
  onSetMeta: (name, content) => {
    // Remove and create a new <meta /> tag in order to make it work
    // with bookmarks in Safari
    const elements = document.getElementsByTagName('meta');
    [].slice.call(elements).forEach((element) => {
      if (element.getAttribute('name') === name) {
        element.parentNode.removeChild(element);
      }
    });
    const meta = document.createElement('meta');
    meta.setAttribute('name', name);
    meta.setAttribute('content', content);
    document.getElementsByTagName('head')[0].appendChild(meta);
  },
};

function run() {
  const scrollOffsets = new Map();
  let currentScrollOffset = null;

  // Make taps on links and buttons work fast on mobiles
  FastClick.attach(document.body);

  const unlisten = Location.listen(location => {
    const locationId = location.pathname + location.search;
    if (!scrollOffsets.get(locationId)) {
      scrollOffsets.set(locationId, Object.create(null));
    }
    currentScrollOffset = scrollOffsets.get(locationId);
    // Restore the scroll position if it was saved
    if (currentScrollOffset.scrollY !== undefined) {
      window.scrollTo(currentScrollOffset.scrollX, currentScrollOffset.scrollY);
    } else {
      window.scrollTo(0, 0);
    }
  });

  const { pathname, search, hash } = window.location;
  const location = `${pathname}${search}${hash}`;

  match({ routes, location }, (error, redirectLocation, renderProps) => {
    render(
      <ContextHolder context={context}>
        <Router {...renderProps} children={routes} history={Location} />
      </ContextHolder>,
      appContainer
    );
    // Remove the pre-rendered CSS because it's no longer used
    // after the React app is launched
    if (cssContainer) {
      cssContainer.parentNode.removeChild(cssContainer);
      cssContainer = null;
    }
  });

  // Save the page scroll position
  const supportPageOffset = window.pageXOffset !== undefined;
  const isCSS1Compat = ((document.compatMode || '') === 'CSS1Compat');
  const setPageOffset = () => {
    if (supportPageOffset) {
      currentScrollOffset.scrollX = window.pageXOffset;
      currentScrollOffset.scrollY = window.pageYOffset;
    } else {
      currentScrollOffset.scrollX = isCSS1Compat ?
        document.documentElement.scrollLeft : document.body.scrollLeft;
      currentScrollOffset.scrollY = isCSS1Compat ?
        document.documentElement.scrollTop : document.body.scrollTop;
    }
  };

  addEventListener(window, 'scroll', setPageOffset);
  addEventListener(window, 'pagehide', () => {
    removeEventListener(window, 'scroll', setPageOffset);
    unlisten();
  });
}

// Run the application when both DOM is ready and page content is loaded
if (['complete', 'loaded', 'interactive'].includes(document.readyState) && document.body) {
  run();
} else {
  document.addEventListener('DOMContentLoaded', run, false);
}