@samitouri / QOS-React / commits / 19bc2dd090

Fix autoFocus for hydration content when it is mismatched (#11737)

* Fix autoFocus for hydration content when it is mismatched * Add a test for mismatched content * Fix a test for production * Fix a spec description and verify console.error output * Run prettier * finalizeInitialChildren always returns `true` * Revert "finalizeInitialChildren always returns `true`" This reverts commit 58edd228046bcafcbcd04a70cb5e78520b50a07e. * Add a TODO comment * Update ReactServerRendering-test.js * Update ReactServerRendering-test.js * Rewrite the comment

Toru Kobayashi committed Dec 7, 2017 at 00:23 UTC 19bc2dd090c44be862bae59c64e89acb8d0827f5
2 files changed +35 -5
packages/react-dom/src/__tests__/ReactServerRendering-test.js
+22
@@ -372,6 +372,28 @@ describe('ReactDOMServer', () => {
372 expect(element.firstChild.focus).not.toHaveBeenCalled();
373 });
374
375 + // Regression test for https://github.com/facebook/react/issues/11726
376 + it('should not focus on either server or client with autofocus={false} even if there is a markup mismatch', () => {
377 + spyOnDev(console, 'error');
378 +
379 + var element = document.createElement('div');
380 + element.innerHTML = ReactDOMServer.renderToString(
381 + <button autoFocus={false}>server</button>,
382 + );
383 + expect(element.firstChild.autofocus).toBe(false);
384 +
385 + element.firstChild.focus = jest.fn();
386 + ReactDOM.hydrate(<button autoFocus={false}>client</button>, element);
387 +
388 + expect(element.firstChild.focus).not.toHaveBeenCalled();
389 + if (__DEV__) {
390 + expect(console.error.calls.count()).toBe(1);
391 + expect(console.error.calls.argsFor(0)[0]).toBe(
392 + 'Warning: Text content did not match. Server: "server" Client: "client"',
393 + );
394 + }
395 + });
396 +
397 it('should throw with silly args', () => {
398 expect(
399 ReactDOMServer.renderToString.bind(ReactDOMServer, {x: 123}),
packages/react-dom/src/client/ReactDOM.js
+13 -5
@@ -704,11 +704,19 @@ const DOMRenderer = ReactFiberReconciler({
704 newProps: Props,
705 internalInstanceHandle: Object,
706 ): void {
707 - ((domElement: any):
708 - | HTMLButtonElement
709 - | HTMLInputElement
710 - | HTMLSelectElement
711 - | HTMLTextAreaElement).focus();
707 + // Despite the naming that might imply otherwise, this method only
708 + // fires if there is an `Update` effect scheduled during mounting.
709 + // This happens if `finalizeInitialChildren` returns `true` (which it
710 + // does to implement the `autoFocus` attribute on the client). But
711 + // there are also other cases when this might happen (such as patching
712 + // up text content during hydration mismatch). So we'll check this again.
713 + if (shouldAutoFocusHostComponent(type, newProps)) {
714 + ((domElement: any):
715 + | HTMLButtonElement
716 + | HTMLInputElement
717 + | HTMLSelectElement
718 + | HTMLTextAreaElement).focus();
719 + }
720 },
721
722 commitUpdate(