Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOM diff and component stack in SSR hydrate mismatch warnings (#10085) #12063

Closed

Conversation

sompylasar
Copy link
Contributor

@sompylasar sompylasar commented Jan 21, 2018

Renders DOM attributes in the tags mentioned in the warnings. Borrows the idea and partially implementation of getNodeSignature from @giles-v #12115

Renders DOM diff and component stack showing visually the location where the hydration failed. Example warning with a diff (see the fixtures/ssr and the tests for more warning examples):

Warning: Expected server HTML to contain a matching <div> in <div>.

  <div>
    {'nested'}
    <!-- -->
    {' '}
    <p>children <b>text</b></p>
+   <div>{['children ', …]}</div>
  </div>

    in div (at SSRMismatchTest.js:280)
    in div (at SSRMismatchTest.js:275)
    in div (at SSRMismatchTest.js:308)
    in SSRMismatchTest (at App.js:14)
    in div (at App.js:11)
    in body (at Chrome.js:17)
    in html (at Chrome.js:9)
    in Chrome (at App.js:10)
    in App (at index.js:8)

react-fixtures-ssr-example

Requires changes to ReactFiberReconciler interface functions that handle hydration errors to distinguish insertion from replacement and show insertion as one added line in the diff; show replacement as one removed, one added line, at correct position among the parentInstance's DOM children:

  • add index (use fiber.index) to point at which child node the insertion or replacement occurs;
  • add isReplaced to distinguish insertion from replacement.
The latest screen recording from fixtures/ssr (7.8MB – click to expand)

react-fixtures-ssr-10mb


Previous revisions
Warning: Expected server HTML to contain a matching <div>{['children ', …]}</div> in <div>nested<!-- --> <p>children <b>text</b></p></div>.
  <div>
    {'nested'}
    {' '}
    <p>children <b>text</b></p>
+   <div>{['children ', …]}</div>
  </div>
    in div (at SSRMismatchTest.js:280)
    in div (at SSRMismatchTest.js:275)
    in div (at SSRMismatchTest.js:308)
    in SSRMismatchTest (at App.js:14)
    in div (at App.js:11)
    in body (at Chrome.js:17)
    in html (at Chrome.js:9)
    in Chrome (at App.js:10)
    in App (at index.js:8)

Extends the proof-of-concept at commit 6c425e7

react-ssr-warning-diff


  • Added textual component stack to the hydrate mismatch warnings
  • Added DOM hydrate mismatch test cases to fixtures/ssr

Example warning:

Warning: Expected server HTML to contain a matching <p> in <div>.
    in p (at SSRMismatchTest.js:40)
    in div (at SSRMismatchTest.js:39)
    in div (at SSRMismatchTest.js:46)
    in SSRMismatchTest (at App.js:14)
    in div (at App.js:11)
    in body (at Chrome.js:17)
    in html (at Chrome.js:9)
    in Chrome (at App.js:10)
    in App (at index.js:8)

react-ssr-mismatch


Fixes #10085

@evan-scott-zocdoc
Copy link

Can this be merged please?

screen shot 2018-02-07 at 1 01 37 pm

^ completely useless

@oyeanuj
Copy link

oyeanuj commented Feb 17, 2018

@sompylasar This is amazing - thank you for the PR! I am wondering for the ssr-children-mismatch case, if it would be helpful and possible to display the client-server mismatch in a diff format as originally suggested by @sebmarkbage in #10085?

@sompylasar
Copy link
Contributor Author

@oyeanuj Thanks, yes, I'll see what I can come up with. Currently, I realized I missed a few cases: warnForDeletedHydratableElement, warnForDeletedHydratableText, warnForInsertedHydratedText that I haven't found how to test yet. So I'll add stack to these first, add tests, then I'm planning to incorporate @giles-v's changes #12115 into this PR (@giles-v please let me know if you don't like the plan).

@giles-v
Copy link

giles-v commented Feb 18, 2018

Hey @sompylasar, thanks for the cite - since the other PR #11215 is approved I would rather it stayed separate. I don’t know the approval / merge timeline.

@evan-scott-zocdoc, since #12115 resolves your issue and should be complete, you may want to leave a comment there too.

@sompylasar
Copy link
Contributor Author

sompylasar commented Feb 18, 2018

FYI, I'm working on a complete set of warning cases, starting at the fixtures app, then translating the findings into the test suite.

Preview screenshot of fixtures/ssr screen shot 2018-02-17 at 9 21 24 pm

@sompylasar sompylasar force-pushed the 10085-nicer-ssr-mismatch-warning branch from 1ab33f4 to 8aca686 Compare February 18, 2018 09:12
@sompylasar
Copy link
Contributor Author

Rebased on top of latest facebook/master@e68c0164

@sompylasar
Copy link
Contributor Author

Here's what I got here so far:

react-ssr

screen_shot_2018-02-18_at_1_22_52_am

@sompylasar
Copy link
Contributor Author

@oyeanuj Hey, have a look, diffs!

screen shot 2018-02-18 at 3 27 57 am


Unfortunately, to make this possible, I had to extend ReactFiberReconciler interface:

   didNotFindHydratableInstance(
     parentType: T,
     parentProps: P,
     parentInstance: I,
     type: T,
     props: P,
+    index: number,
   ): void,

and modify ReactFiberHydrationContext to pass the index from the fiber:

               didNotFindHydratableInstance(
                 parentType,
                 parentProps,
                 parentInstance,
                 type,
                 props,
+                fiber.index,
               );

into warnForInsertedHydratedElement:

     didNotFindHydratableInstance(
       parentType: string,
       parentProps: Props,
       parentInstance: Instance,
       type: string,
       props: Props,
+      index: number,
     ) {
       if (__DEV__ && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
-        warnForInsertedHydratedElement(parentInstance, type, props);
+        warnForInsertedHydratedElement(parentInstance, type, props, index);
       }
     },

I haven't cleaned up the diff building code and haven't updated the tests so please bare with me, it's yet a POC: sompylasar@6c425e7

@pull-bot
Copy link

pull-bot commented Feb 18, 2018

Details of bundled changes.

Comparing: b87aabd...1a15f08

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.development.js +1.5% +1.4% 645.84 KB 655.72 KB 151.35 KB 153.47 KB UMD_DEV
react-dom.development.js +1.5% +1.4% 641.19 KB 651.06 KB 149.96 KB 152.08 KB NODE_DEV
ReactDOM-dev.js +1.6% +1.5% 663.57 KB 674.41 KB 152.32 KB 154.62 KB FB_WWW_DEV

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js +0.3% +0.3% 439.51 KB 440.97 KB 98.53 KB 98.81 KB UMD_DEV
react-art.development.js +0.4% +0.3% 371.26 KB 372.72 KB 81.41 KB 81.69 KB NODE_DEV
ReactART-dev.js +0.4% +0.4% 376.26 KB 377.94 KB 80.17 KB 80.49 KB FB_WWW_DEV

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-test-renderer.development.js +0.4% +0.3% 383.26 KB 384.72 KB 83.99 KB 84.27 KB UMD_DEV
react-test-renderer.development.js +0.4% +0.3% 378.85 KB 380.31 KB 82.85 KB 83.14 KB NODE_DEV
ReactTestRenderer-dev.js +0.4% +0.4% 383.97 KB 385.64 KB 81.88 KB 82.21 KB FB_WWW_DEV

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js +0.4% +0.4% 367.16 KB 368.62 KB 79.52 KB 79.8 KB NODE_DEV
react-reconciler-persistent.development.js +0.4% +0.4% 365.7 KB 367.16 KB 78.95 KB 79.23 KB NODE_DEV

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-dev.js +0.3% +0.3% 498.55 KB 500.23 KB 110.4 KB 110.72 KB RN_FB_DEV
ReactNativeRenderer-dev.js +0.3% +0.3% 498.29 KB 499.96 KB 110.33 KB 110.65 KB RN_OSS_DEV
ReactFabric-dev.js +0.3% +0.3% 488.74 KB 490.41 KB 107.98 KB 108.3 KB RN_FB_DEV
ReactFabric-dev.js +0.3% +0.3% 488.77 KB 490.44 KB 108 KB 108.32 KB RN_OSS_DEV

schedule

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
schedule.development.js n/a n/a 0 B 19.17 KB 0 B 5.74 KB UMD_DEV
schedule.production.min.js n/a n/a 0 B 3.16 KB 0 B 1.53 KB UMD_PROD

Generated by 🚫 dangerJS

@sompylasar
Copy link
Contributor Author

Add diff to hydrate warnings (#10085)

Renders DOM attributes in the tags mentioned in the warnings. Borrows the idea and partially implementation of getNodeSignature from @giles-v #12115

Renders DOM diff showing visually the location where the hydration failed. Example warning with a diff:

Warning: Expected server HTML to contain a matching <div>{['children ', …]}</div> in <div>nested<!-- --> <p>children <b>text</b></p></div>.
  <div>
    {'nested'}
    {' '}
    <p>children <b>text</b></p>
+   <div>{['children ', …]}</div>
  </div>
    in div (at SSRMismatchTest.js:280)
    in div (at SSRMismatchTest.js:275)
    in div (at SSRMismatchTest.js:308)
    in SSRMismatchTest (at App.js:14)
    in div (at App.js:11)
    in body (at Chrome.js:17)
    in html (at Chrome.js:9)
    in Chrome (at App.js:10)
    in App (at index.js:8)

Requires changes to ReactFiberReconciler interface functions that handle hydration errors to distinguish insertion from replacement and show insertion as one added line in the diff; show replacement as one removed, one added line, at correct position among the parentInstance's DOM children:

  • add index (use fiber.index) to point at which child node the insertion or replacement occurs;
  • add isReplaced to distinguish insertion from replacement.

Extends the proof-of-concept at commit 6c425e7

react-ssr-warning-diff


See the tests for more warning examples.

@sompylasar
Copy link
Contributor Author

sompylasar commented Feb 26, 2018

The most recent CircleCI build failure reason is unrelated to this PR:

``` $ node ./scripts/tasks/danger Request failed [401]: https://api.github.com/repos/facebook/react/pulls/12063 Response: { "message": "Bad credentials", "documentation_url": "https://developer.github.com/v3" } Request failed [401]: https://api.github.com/repos/facebook/react/pulls/12063/commits Response: { "message": "Bad credentials", "documentation_url": "https://developer.github.com/v3" } Request failed [401]: https://api.github.com/repos/facebook/react/pulls/12063 Response: { "message": "Bad credentials", "documentation_url": "https://developer.github.com/v3" } Request failed [401]: https://api.github.com/repos//issues/12063 Response: { "message": "Bad credentials", "documentation_url": "https://developer.github.com/v3" } Request failed [401]: https://api.github.com/repos/facebook/react/pulls/12063/commits Response: { "message": "Bad credentials", "documentation_url": "https://developer.github.com/v3" } Request failed [401]: https://api.github.com/repos/facebook/react/pulls/12063/reviews Response: { "message": "Bad credentials", "documentation_url": "https://developer.github.com/v3" } Request failed [401]: https://api.github.com/repos/facebook/react/pulls/12063/requested_reviewers Response: { "message": "Bad credentials", "documentation_url": "https://developer.github.com/v3" } Error: TypeError: Cannot read property 'repo' of undefined at GitHub.APIMetadataForPR (/home/circleci/project/node_modules/danger/distribution/platforms/GitHub.js:274:27) at GitHub. (/home/circleci/project/node_modules/danger/distribution/platforms/GitHub.js:164:39) at step (/home/circleci/project/node_modules/danger/distribution/platforms/GitHub.js:40:23) at Object.next (/home/circleci/project/node_modules/danger/distribution/platforms/GitHub.js:21:53) at fulfilled (/home/circleci/project/node_modules/danger/distribution/platforms/GitHub.js:12:58) at at process._tickCallback (internal/process/next_tick.js:188:7) Danger failed ```
Received return code 0 from: ./scripts/circleci/build.sh
Received return code 0 from: yarn test-build --maxWorkers=2
Received return code 0 from: yarn test-build-prod --maxWorkers=2
Received return code 1 from: node ./scripts/tasks/danger
Received return code 0 from: ./scripts/circleci/upload_build.sh
Exited with code 1

@sompylasar sompylasar changed the title Component stack in SSR hydrate mismatch warnings (#10085) DOM diff and component stack in SSR hydrate mismatch warnings (#10085) Feb 26, 2018
@@ -946,18 +946,28 @@ const DOMRenderer = ReactFiberReconciler({
parentContainer: Container,
type: string,
props: Props,
index: number,
isReplaced: boolean,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@acdlite Hi,

This PR is about showing a nice DOM diff and a component stack in the hydration mismatch warnings for developers.

To implement the diff I had to add two additional arguments 1) index: number and 2) isReplaced: boolean to the ReactFiberReconciler's didNotFindHydratable* methods to pass down to the warning-generating functions 1) the index of the child node that's being hydrated within the parent node's hydratable children and 2) the fact that it's being replaced or inserted.

The index is required to show the minus/plus diff prefix at the correct line when looping through the parent node's hydratable children while constructing the diff.

The isReplaced fact is required to not add the minus diff prefix when the preceding sibling node was not in fact removed during hydration.

Example warning when the <p> element did not match and was replaced with the <div> element (isReplaced: true):

Warning: Expected server HTML to contain a matching <div>{['children ', …]}</div>
 in <div>nested<!-- --> <p>children <b>text</b></p></div>.
  <div>
    {'nested'}
    {' '}
-   <p>children <b>text</b></p>
+   <div>{['children ', …]}</div>
  </div>
    in div (at **)
    in Component (at **)

Example warning when the <p> element did match thus not removed/replaced, the <div> element was added (isReplaced: false):

Warning: Expected server HTML to contain a matching <div>{['children ', …]}</div>
 in <div>nested<!-- --> <p>children <b>text</b></p></div>.
  <div>
    {'nested'}
    {' '}
    <p>children <b>text</b></p>
+   <div>{['children ', …]}</div>
  </div>
    in div (at **)
    in Component (at **)

Could you please approve this change or recommend another direction?

Thank you.

@oyeanuj
Copy link

oyeanuj commented Mar 25, 2018

@sompylasar Thank you for all your work on this PR! Hopefully, we can get this reviewed soon and merged!

cc: @mxstbr @aickin

@acdlite
Copy link
Collaborator

acdlite commented Mar 27, 2018

Hey sorry for the lack of review so far. Been pretty busy preparing for 16.3. We'll try our best to look at this soon.

@sompylasar
Copy link
Contributor Author

@acdlite Sure, no worries, at least thank you for giving the notice here. Good luck with 16.3, looking forward to it.

@redonkulus
Copy link

@acdlite @sompylasar can this PR be re-based and reviewed soon?

@gaearon
Copy link
Collaborator

gaearon commented May 13, 2018

Sorry, it's still hard to find the time. I think a better strategy is to get someone who's actively using React SSR (cc @rauchg) to help out with testing this and reviewing.

@KidkArolis
Copy link

fwiw, I ran this branch locally in an SSR project. Works well, prints more useful info than<div> in <div>.

image

Could be formatted slightly better (?), e.g. the first bit is very long in my case, perhaps split X and Y in Did not expect X in Y into multiple lines. Something like:

Server html mismatch. Did not expect to see

<some html...>

in

<some other html...>
-  <some html...>

@KidkArolis
Copy link

Ah, I didn't understand this error message at first, since those long divs kind of all got jumbled, didn't notice the . in there separating the X in Y from the diff. What about adding some wording and spacing around diff:

Warning: Did not expect server HTML to contain <div class="Layout-frzSyd ixtuiM" data-reactroot=""><div class="Layout__Head-hrSJTM kvjsNA"><div class="Header__HeaderBar-cloUtd qfmIf"><div class="Head…</div> in <div class="root"><div class="Layout-frzSyd ixtuiM" data-reactroot=""><div class="Layout__Head-hrSJTM kvjsNA"><div cla…</div>

Diff:

<div class="root">
-  <div class="Layout-frzSyd ixtuiM" data-reactroot=""><div class="Layout__Head-hrSJTM kvjsNA"><div class="Header__HeaderBar-cloUtd qfmI"><div class="Head…</div>
</div>

My actual issue was that the client was trying to render an empty app. This new diffing feature is very helpful have I realised where the diff begins.

@KidkArolis
Copy link

Or even something like:

Warning: Did not expect server HTML to contain <div class="Layout-frzSyd ixtuiM" data-react…</div> in <div class="root"><div class="Layout-frzSydixtu…</div>

Server HTML:

              <div class="root">
unexpected »    <div class="Layout-frzSyd ixtuiM" data-reactroot=""><div class="Layout__Head-hrSJTM kvjsNA"><div class="Header__HeaderBar-cloUtd qfmI"><div class="Head…</div>
              </div>

@sompylasar
Copy link
Contributor Author

@KidkArolis Yes, valid suggestions, the readability can be improved.

@sompylasar sompylasar force-pushed the 10085-nicer-ssr-mismatch-warning branch 2 times, most recently from b34d07b to 9afbc48 Compare May 22, 2018 19:29
@sompylasar
Copy link
Contributor Author

👆Rebased to the current facebook/master.

@mxstbr
Copy link
Contributor

mxstbr commented Jun 7, 2018

@sompylasar can you publish this to @sompylasar/react and @sompylasar/react-dom so that we can test it in our app?

@gaearon
Copy link
Collaborator

gaearon commented Aug 1, 2018

Before we go too far into that route I'd like to better understand why we need indexing at all. Since we're able to insert/delete at the right place, why don't we have sufficient information for creating the diff?

@sompylasar
Copy link
Contributor Author

Before we go too far into that route I'd like to better understand why we need indexing at all. Since we're able to insert/delete at the right place, why don't we have sufficient information for creating the diff?

As I figured out, the "right place" hydration state is maintained implicitly within the reconciler program via the "instruction counter" (i.e. at which point of the program is the JS engine now, how many host nodes within a parent host node the reconciliation code has passed via getNextHydratableSibling and hydrated successfully so far, up to when the mismatch has occurred).

export function getNextHydratableSibling(
instance: Instance | TextInstance,
): null | Instance | TextInstance {
let node = instance.nextSibling;
// Skip non-hydratable nodes.
while (
node &&
node.nodeType !== ELEMENT_NODE &&
node.nodeType !== TEXT_NODE
) {
node = node.nextSibling;
}
return (node: any);
}

This host node hydration index is required because the real DOM which we traverse and display in the diff contains more nodes than were hydrated (i.e. matched with the virtual DOM rendered by the components), but the program does not know how many the reconciler has passed/skipped (from the beginning of the parent node) and how many remain unreconciled (from the end of the parent node).

If getNextHydratableSibling returned the number of nodes it skipped within its loop, the reconciler program could have accumulated these numbers into an explicit hydration state variable as it goes, but getNextHydratableSibling API is constrained by the ReactFiberHostConfig interface so I cannot change its return value type.

@gaearon
Copy link
Collaborator

gaearon commented Aug 2, 2018

but getNextHydratableSibling API is constrained by the ReactFiberHostConfig interface so I cannot change its return value type.

Let's say we can change any APIs related to hydration in the host config, but we have a new constraint: the diffing and formatting logic should be in the reconciler, and any renderer with hydration should get warnings with diffs “for free”.

How would you solve that problem?

Copy link
Collaborator

@gaearon gaearon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would diffing look like if it was implemented in the reconciler? Feel free to change host config API if necessary — the goal is that all hydratable renderers would get nice warnings, not just DOM.

@sompylasar
Copy link
Contributor Author

Would you like a separate branch/PR from scratch for that, or keep it all here?

@gaearon
Copy link
Collaborator

gaearon commented Aug 2, 2018

What's more convenient for you? Separate is fine as long as we carry tests over.

@sompylasar sompylasar force-pushed the 10085-nicer-ssr-mismatch-warning branch 2 times, most recently from c022a52 to 7d2c991 Compare September 8, 2018 06:29
* Add into existing fixture, not as a new one, to avoid duplicating
server-rendering and hot-reloading code.
* Add the browser-side counterpart for the `url` that was already
passed to `render` at the server but wasn't used. Pass it down to the
`App` component.
Next, will add a test per every case.
Example warning:
```
Warning: Expected server HTML to contain a matching <em> in <div>.
 <div className="SSRMismatchTest__wrapper">
   …
   <span className="SSRMismatchTest__2">2</span>
   <span className="SSRMismatchTest__3">3</span>
   <span className="SSRMismatchTest__4">4</span>
   <span className="SSRMismatchTest__5">5</span>
   <span className="SSRMismatchTest__6">6</span>
-  <strong> SSRMismatchTest default text </strong>
+  <em />
   <span className="SSRMismatchTest__7">7</span>
   <span className="SSRMismatchTest__8">8</span>
   <span className="SSRMismatchTest__9">9</span>
   <span className="SSRMismatchTest__10">10</span>
   <span className="SSRMismatchTest__11">11</span>
   …
 </div>

    in em (at SSRMismatchTest.js:224)
    in div (at SSRMismatchTest.js:217)
    in div (at SSRMismatchTest.js:283)
    in SSRMismatchTest (at App.js:14)
    in div (at App.js:11)
    in body (at Chrome.js:17)
    in html (at Chrome.js:9)
    in Chrome (at App.js:10)
    in App (at index.js:8)
```

https://user-images.githubusercontent.com/498274/36351251-d04e8fca-145b-11e8-995d-389e0ae99456.png
Renders DOM attributes in the tags mentioned in the warnings. Borrows the idea and partially implementation of `getNodeSignature` from @giles-v facebook#12115

Renders DOM diff showing visually the location where the hydration failed. Example warning with a diff:
```
Warning: Expected server HTML to contain a matching <div>{['children ', …]}</div> in <div>nested<!-- --> <p>children <b>text</b></p></div>.
  <div>
    {'nested'}
    {' '}
    <p>children <b>text</b></p>
+   <div>{['children ', …]}</div>
  </div>
    in div (at SSRMismatchTest.js:280)
    in div (at SSRMismatchTest.js:275)
    in div (at SSRMismatchTest.js:308)
    in SSRMismatchTest (at App.js:14)
    in div (at App.js:11)
    in body (at Chrome.js:17)
    in html (at Chrome.js:9)
    in Chrome (at App.js:10)
    in App (at index.js:8)
```

Requires changes to ReactFiberReconciler interface functions that handle hydration errors to distinguish insertion from replacement and show insertion as one added line in the diff; show replacement as one removed, one added line, at correct position among the parentInstance's DOM children:
- add `index` (use `fiber.index`) to point at which child node the insertion or replacement occurs;
- add `isReplaced` to distinguish insertion from replacement.

Extends the proof-of-concept at commit a5e9a70

https://user-images.githubusercontent.com/498274/36652198-11bb46fe-1a62-11e8-9fa2-a612827d1463.gif
- Change headline to contain only the tag names, not attributes and children.
- Add newlines between headline, diff, and stack.

Besides the above feedback:
- Add comment nodes display in the diff.
- Add weird node handling in the diff.
When going through the fixtures one by one it's convenient to see the server-side rendered markup in the Chrome DevTools Elements along with the generated warning in Console. The placeholder element adds consistency to the markup: it does not disappear with page reloads, so Chrome DevTools is smart enough to keep it focused.
Stick to ASCII in the source code to avoid potential cross-browser compatibility and charset issues.
…diff

```
  ● ReactMount › should warn when hydrate replaces an element within server-rendered nested components

    Error: Unexpected warning recorded: - Expected
    + Received

      Warning: Expected server HTML to contain a matching <h2> in <div>.

        <div data-reactroot="">
          <div data-ssr-mismatch-padding-before="1"></div>
    -     <div data-ssr-mismatch-padding-before="2"></div>
    + -   <div data-ssr-mismatch-padding-before="2"></div>
    + +   <h2>SSRMismatchTest default text</h2>
          <div data-ssr-mismatch-padding-before="3"></div>
          <div data-ssr-mismatch-padding-before="4"></div>
          <div data-ssr-mismatch-padding-before="5"></div>
    - -   <h1>SSRMismatchTest default text</h1>
    - +   <h2>SSRMismatchTest default text</h2>
    +     <h1>SSRMismatchTest default text</h1>
          <span></span>
          <div data-ssr-mismatch-padding-after="1"></div>
          <div data-ssr-mismatch-padding-after="2"></div>
          <div data-ssr-mismatch-padding-after="3"></div>
          <div data-ssr-mismatch-padding-after="4"></div>
          <div data-ssr-mismatch-padding-after="5"></div>
        </div>

          in h2 (at **)
          in div (at **)
          in TestNestedComponent (at **)
          in TestComponent (at **)
```
…ot stack

The stack was required to track where to return after child siblings traversal.

The `fiber.return` pointers were made for that purpose,
it's safe to overwrite them because they are only used to traverse the fiber tree,
and their values outside the traversal functions are not relied upon.

One test fails for yet unknown reason, the text node is inserted too early:
```
  ● ReactMount › should warn when hydrate inserts a text node after matching elements (insertion diff)

    Error: Unexpected warning recorded: - Expected
    + Received

      Warning: Expected server HTML to contain a matching text node for {'SSRMismatchTest client text'} in <div>.

        <div data-reactroot="">
          <div data-ssr-mismatch-padding-before="1"><span></span></div>
          <div data-ssr-mismatch-padding-before="2"></div>
    + +   {'SSRMismatchTest client text'}
          <div data-ssr-mismatch-padding-before="3"></div>
          <div data-ssr-mismatch-padding-before="4"></div>
          <div data-ssr-mismatch-padding-before="5"></div>
          <div data-ssr-mismatch-padding-before="6"></div>
          <div data-ssr-mismatch-padding-before="7"></div>
          <div data-ssr-mismatch-padding-before="8"></div>
          <div data-ssr-mismatch-padding-before="9"></div>
          <div data-ssr-mismatch-padding-before="10"></div>
          <div data-ssr-mismatch-padding-before="11"></div>
          <div data-ssr-mismatch-padding-before="12"></div>
          <div data-ssr-mismatch-padding-before="13"></div>
    - +   {'SSRMismatchTest client text'}
        </div>

          in div (at **)
```
@sompylasar
Copy link
Contributor Author

A separate PR submitted here: #13602 – it's still work-in-progress as of now.

@sompylasar
Copy link
Contributor Author

PR #13602 seems to have reached solid enough state to replace this one, so if the design decision of moving the warnings to the reconciler holds, should we close this and focus on the reconciler one?

@stale
Copy link

stale bot commented Jan 10, 2020

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution.

@stale stale bot added the Resolution: Stale Automatically closed due to inactivity label Jan 10, 2020
@sompylasar
Copy link
Contributor Author

Okay, stale[bot], I guess we can close this one, as nobody's been looking at it, and focus on #13602 instead.

@sompylasar sompylasar closed this Jan 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed Resolution: Stale Automatically closed due to inactivity
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nicer Formatting of SSR Validation