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 58edd22804.

* Add a TODO comment

* Update ReactServerRendering-test.js

* Update ReactServerRendering-test.js

* Rewrite the comment
This commit is contained in:
Toru Kobayashi
2017-12-06 15:23:37 +00:00
committed by Dan Abramov
parent 5bd2321ae3
commit 19bc2dd090
2 changed files with 35 additions and 5 deletions
@@ -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}),
+13 -5
View File
@@ -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(