Skip to content

Commit 8aeea5a

Browse files
nhunzakergaearon
authored andcommitted
Do not assign node.value on input creation if no change will occur (#12925)
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
1 parent aa85b0f commit 8aeea5a

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

fixtures/dom/src/components/fixtures/text-inputs/index.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,36 @@ class TextInputFixtures extends React.Component {
6464
<Fixture>
6565
<form className="control-box">
6666
<fieldset>
67-
<legend>Text</legend>
67+
<legend>Empty value prop string</legend>
68+
<input value="" required={true} />
69+
</fieldset>
70+
<fieldset>
71+
<legend>No value prop</legend>
6872
<input required={true} />
6973
</fieldset>
7074
<fieldset>
71-
<legend>Date</legend>
75+
<legend>Empty defaultValue prop string</legend>
76+
<input required={true} defaultValue="" />
77+
</fieldset>
78+
<fieldset>
79+
<legend>No value prop date input</legend>
7280
<input type="date" required={true} />
7381
</fieldset>
82+
<fieldset>
83+
<legend>Empty value prop date input</legend>
84+
<input type="date" value="" required={true} />
85+
</fieldset>
7486
</form>
7587
</Fixture>
7688

7789
<p className="footnote">
7890
Checking the date type is also important because of a prior fix for
7991
iOS Safari that involved assigning over value/defaultValue
80-
properties of the input to prevent a display bug. This also
81-
triggered input validation.
92+
properties of the input to prevent a display bug. This also triggers
93+
input validation.
94+
</p>
95+
<p className="footnote">
96+
The date inputs should be blank in iOS. This is not a bug.
8297
</p>
8398
</TestCase>
8499

packages/react-dom/src/client/ReactDOMFiberInput.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,16 +209,24 @@ export function postMountWrapper(element: Element, props: Object) {
209209
const node = ((element: any): InputWithWrapperState);
210210

211211
if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
212+
const initialValue = '' + node._wrapperState.initialValue;
213+
const currentValue = node.value;
214+
212215
// Do not assign value if it is already set. This prevents user text input
213216
// from being lost during SSR hydration.
214-
if (node.value === '') {
215-
node.value = '' + node._wrapperState.initialValue;
217+
if (currentValue === '') {
218+
// Do not re-assign the value property if there is no change. This
219+
// potentially avoids a DOM write and prevents Firefox (~60.0.1) from
220+
// prematurely marking required inputs as invalid
221+
if (initialValue !== currentValue) {
222+
node.value = initialValue;
223+
}
216224
}
217225

218226
// value must be assigned before defaultValue. This fixes an issue where the
219227
// visually displayed value of date inputs disappears on mobile Safari and Chrome:
220228
// https://github.com/facebook/react/issues/7233
221-
node.defaultValue = '' + node._wrapperState.initialValue;
229+
node.defaultValue = initialValue;
222230
}
223231

224232
// Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug

0 commit comments

Comments
 (0)