From b7c136d603c9f665d96dbd62b1e5a70d631e5c76 Mon Sep 17 00:00:00 2001 From: Nathan Hunzaker Date: Tue, 29 May 2018 07:25:56 -0400 Subject: [PATCH] Do not assign node.value on input creation if no change will occur This commit fixes an issue where assigning an empty string to required text inputs triggers the invalid state in Firefox (~60.0.1). It does this by first comparing the initial state value to the current value property on the text element. This: 1. Prevents the validation issue 2. Avoids an extra DOM Mutation in some cases --- .../components/fixtures/text-inputs/index.js | 23 +++++++++++++++---- .../src/client/ReactDOMFiberInput.js | 14 ++++++++--- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/fixtures/dom/src/components/fixtures/text-inputs/index.js b/fixtures/dom/src/components/fixtures/text-inputs/index.js index af71edcbb5c..33639686a31 100644 --- a/fixtures/dom/src/components/fixtures/text-inputs/index.js +++ b/fixtures/dom/src/components/fixtures/text-inputs/index.js @@ -64,21 +64,36 @@ class TextInputFixtures extends React.Component {
- Text + Empty value prop string + +
+
+ No value prop
- Date + Empty defaultValue prop string + +
+
+ No value prop date input
+
+ Empty value prop date input + +

Checking the date type is also important because of a prior fix for iOS Safari that involved assigning over value/defaultValue - properties of the input to prevent a display bug. This also - triggered input validation. + properties of the input to prevent a display bug. This also triggers + input validation. +

+

+ The date inputs should be blank in iOS. This is not a bug.

diff --git a/packages/react-dom/src/client/ReactDOMFiberInput.js b/packages/react-dom/src/client/ReactDOMFiberInput.js index fd5a574fec3..475b444b55d 100644 --- a/packages/react-dom/src/client/ReactDOMFiberInput.js +++ b/packages/react-dom/src/client/ReactDOMFiberInput.js @@ -209,16 +209,24 @@ export function postMountWrapper(element: Element, props: Object) { const node = ((element: any): InputWithWrapperState); if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) { + const initialValue = '' + node._wrapperState.initialValue; + const currentValue = node.value; + // Do not assign value if it is already set. This prevents user text input // from being lost during SSR hydration. - if (node.value === '') { - node.value = '' + node._wrapperState.initialValue; + if (currentValue === '') { + // Do not re-assign the value property if there is no change. This + // potentially avoids a DOM write and prevents Firefox (~60.0.1) from + // prematurely marking required inputs as invalid + if (initialValue !== currentValue) { + node.value = initialValue; + } } // value must be assigned before defaultValue. This fixes an issue where the // visually displayed value of date inputs disappears on mobile Safari and Chrome: // https://github.com/facebook/react/issues/7233 - node.defaultValue = '' + node._wrapperState.initialValue; + node.defaultValue = initialValue; } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug