How to view client markup to debug checksum errors in react

2.2k views Asked by At

I have a checksum error with my isomorphic rendering of an apollo graphQL connected page. How can I view the client markup so that I can debug what the differences are? Any other tips to track down how the rendering is different on the server side vs client-side? When I try to inspect element with Chrome - all I'm getting it seems is the server rendered output so I can't be sure how the client output is differing.

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

The only guess I can make from the truncated warning message is that the Login element is appearing outside of the header (since the only thing on the page that starts with "Lo" is Login).. but I can't be sure that's the right guess because it seems pretty strange. Thus, I'd like to verify with the actual client markup to make sure that is indeed the difference.

3

There are 3 answers

0
Oliver Joseph Ash On

I have found that it's useful to increase the amount of surrounding context shown. This can only be done by modifying the code in the react-dom package:

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;

As an aside, patch-package is a very useful tool for making changes to packages in node_modules.

2
Jesper We On

Sounds too easy, but isn't it just to dump document.body.outerHTML in Chrome?

0
saeta On

I had to read about this and I tried different ways.

This may sound crazy but this way worked fine for me.

Wrap your React markup in an extra <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>
);

Originally, GitHunt Example doesn't have this extra div https://github.com/apollostack/GitHunt-React/blob/master/ui/routes/Html.js#L18

I hope thats helps.