Skip to content

Commit

Permalink
Fix autoFocus for hydration content when it is mismatched (#11737)
Browse files Browse the repository at this point in the history
* 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 58edd22.

* Add a TODO comment

* Update ReactServerRendering-test.js

* Update ReactServerRendering-test.js

* Rewrite the comment
  • Loading branch information
koba04 authored and gaearon committed Dec 6, 2017
1 parent 5bd2321 commit 19bc2dd
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
22 changes: 22 additions & 0 deletions packages/react-dom/src/__tests__/ReactServerRendering-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,28 @@ describe('ReactDOMServer', () => {
expect(element.firstChild.focus).not.toHaveBeenCalled();
});

// Regression test for https://github.com/facebook/react/issues/11726
it('should not focus on either server or client with autofocus={false} even if there is a markup mismatch', () => {
spyOnDev(console, 'error');

var element = document.createElement('div');
element.innerHTML = ReactDOMServer.renderToString(
<button autoFocus={false}>server</button>,
);
expect(element.firstChild.autofocus).toBe(false);

element.firstChild.focus = jest.fn();
ReactDOM.hydrate(<button autoFocus={false}>client</button>, element);

expect(element.firstChild.focus).not.toHaveBeenCalled();
if (__DEV__) {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toBe(
'Warning: Text content did not match. Server: "server" Client: "client"',
);
}
});

it('should throw with silly args', () => {
expect(
ReactDOMServer.renderToString.bind(ReactDOMServer, {x: 123}),
Expand Down
18 changes: 13 additions & 5 deletions packages/react-dom/src/client/ReactDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -704,11 +704,19 @@ const DOMRenderer = ReactFiberReconciler({
newProps: Props,
internalInstanceHandle: Object,
): void {
((domElement: any):
| HTMLButtonElement
| HTMLInputElement
| HTMLSelectElement
| HTMLTextAreaElement).focus();
// Despite the naming that might imply otherwise, this method only
// fires if there is an `Update` effect scheduled during mounting.
// This happens if `finalizeInitialChildren` returns `true` (which it
// does to implement the `autoFocus` attribute on the client). But
// there are also other cases when this might happen (such as patching
// up text content during hydration mismatch). So we'll check this again.
if (shouldAutoFocusHostComponent(type, newProps)) {
((domElement: any):
| HTMLButtonElement
| HTMLInputElement
| HTMLSelectElement
| HTMLTextAreaElement).focus();
}
},

commitUpdate(
Expand Down

0 comments on commit 19bc2dd

Please sign in to comment.