1

我的 apollo graphQL 连接页面的同构渲染出现校验和错误。如何查看客户端标记以便调试差异是什么?还有其他技巧可以追踪服务器端与客户端的渲染有何不同?当我尝试使用 Chrome 检查元素时 - 我得到的似乎是服务器呈现的输出,所以我无法确定客户端输出有何不同。

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) </div></header><div data-reactid="18">Lo
 (server) </div></header><div class="Home-root-2IM

我可以从截断的警告消息中做出的唯一猜测是登录元素出现在标题之外(因为页面上唯一以“Lo”开头的东西是登录)..但我不能确定那是正确的猜测,因为它看起来很奇怪。因此,我想使用实际的客户端标记进行验证,以确保确实存在差异。

4

3 回答 3

0

我发现增加显示的周围上下文的数量很有用。这只能通过修改 react-dom 包中的代码来完成:

diff --git a/node_modules/react-dom/lib/ReactMount.js b/node_modules/react-dom/lib/ReactMount.js
index bb7d5bf..675a7bd 100644
--- a/node_modules/react-dom/lib/ReactMount.js
+++ b/node_modules/react-dom/lib/ReactMount.js
@@ -499,7 +499,9 @@ var ReactMount = {
         }

         var diffIndex = firstDifferenceIndex(normalizedMarkup, rootMarkup);
-        var difference = ' (client) ' + normalizedMarkup.substring(diffIndex - 20, diffIndex + 20) + '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20);
+        // Print num lines of leading and trailing context surrounding
+        var differenceContext = 40;
+        var difference = ' (client) ' + normalizedMarkup.substring(diffIndex - differenceContext, diffIndex + differenceContext) + '\n (server) ' + rootMarkup.substring(diffIndex - differenceContext, diffIndex + differenceContext);

         !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\'re trying to render a component to the document using server rendering but the checksum was invalid. This usually means you rendered a different component type or props on the client from the one on the server, or your render() methods are impure. React cannot handle this case due to cross-browser quirks by rendering at the document root. You should look for environment dependent code in your components and ensure the props are the same client and server side:\n%s', difference) : _prodInvariant('42', difference) : void 0;

顺便说一句,patch-package是一个非常有用的工具,用于更改node_modules.

于 2017-12-28T18:19:28.100 回答
0

听起来太简单了,但不只是转储document.body.outerHTML到 Chrome 中吗?

于 2017-01-17T15:27:24.023 回答
0

我不得不阅读这个,我尝试了不同的方法。

这听起来可能很疯狂,但这种方式对我来说效果很好。

将你的 React 标记包装在一个额外的<div>.

const Html = ({ content, state }) => (
  <html lang="en">
    <head>
      <meta charSet="utf-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossOrigin="anonymous" />
      <title>Teaching Framework</title>
    </head>
    <body>
      <div id="content">
        <div dangerouslySetInnerHTML={{ __html: content }} /> <--- HERE
      </div>
      <div id="footer">
        <ul>
          <li>Footer</li>
        </ul>
      </div>
      <script
        dangerouslySetInnerHTML={{ __html: `window.__APOLLO_STATE__=${JSON.stringify(state)};` }}
        charSet="UTF-8"
      />
      <script src={scriptUrl} charSet="UTF-8" />
    </body>
  </html>
);

最初,GitHunt Example 没有这个额外的 div https://github.com/apollostack/GitHunt-React/blob/master/ui/routes/Html.js#L18

我希望这会有所帮助。

于 2017-01-28T21:22:58.487 回答