Skip to content

Commit ad3318e

Browse files
committed
Revert "Don't update textarea defaultValue and input checked unnecessarily (#26580)"
This reverts commit 9a9da77.
1 parent 87fb8ea commit ad3318e

File tree

4 files changed

+14
-78
lines changed

4 files changed

+14
-78
lines changed

packages/react-dom-bindings/src/client/ReactDOMInput.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export function validateInputProps(element: Element, props: Object) {
8484
export function updateInputChecked(element: Element, props: Object) {
8585
const node: HTMLInputElement = (element: any);
8686
const checked = props.checked;
87-
if (checked != null && node.checked !== !!checked) {
87+
if (checked != null) {
8888
node.checked = checked;
8989
}
9090
}

packages/react-dom-bindings/src/client/ReactDOMTextarea.js

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ export function validateTextareaProps(element: Element, props: Object) {
6161
export function updateTextarea(element: Element, props: Object) {
6262
const node: HTMLTextAreaElement = (element: any);
6363
const value = getToStringValue(props.value);
64+
const defaultValue = getToStringValue(props.defaultValue);
65+
if (defaultValue != null) {
66+
node.defaultValue = toString(defaultValue);
67+
} else {
68+
node.defaultValue = '';
69+
}
6470
if (value != null) {
6571
// Cast `value` to a string to ensure the value is set correctly. While
6672
// browsers typically do this as necessary, jsdom doesn't.
@@ -70,19 +76,10 @@ export function updateTextarea(element: Element, props: Object) {
7076
node.value = newValue;
7177
}
7278
// TOOO: This should respect disableInputAttributeSyncing flag.
73-
if (props.defaultValue == null) {
74-
if (node.defaultValue !== newValue) {
75-
node.defaultValue = newValue;
76-
}
77-
return;
79+
if (props.defaultValue == null && node.defaultValue !== newValue) {
80+
node.defaultValue = newValue;
7881
}
7982
}
80-
const defaultValue = getToStringValue(props.defaultValue);
81-
if (defaultValue != null) {
82-
node.defaultValue = toString(defaultValue);
83-
} else {
84-
node.defaultValue = '';
85-
}
8683
}
8784

8885
export function initTextarea(element: Element, props: Object) {

packages/react-dom/src/__tests__/ReactDOMComponent-test.js

Lines changed: 5 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,63 +1043,6 @@ describe('ReactDOMComponent', () => {
10431043
expect(nodeValueSetter).toHaveBeenCalledTimes(2);
10441044
});
10451045

1046-
it('should not incur unnecessary DOM mutations for controlled string properties', () => {
1047-
function onChange() {}
1048-
const container = document.createElement('div');
1049-
ReactDOM.render(<input value="" onChange={onChange} />, container);
1050-
1051-
const node = container.firstChild;
1052-
1053-
let nodeValue = '';
1054-
const nodeValueSetter = jest.fn();
1055-
Object.defineProperty(node, 'value', {
1056-
get: function () {
1057-
return nodeValue;
1058-
},
1059-
set: nodeValueSetter.mockImplementation(function (newValue) {
1060-
nodeValue = newValue;
1061-
}),
1062-
});
1063-
1064-
ReactDOM.render(<input value="foo" onChange={onChange} />, container);
1065-
expect(nodeValueSetter).toHaveBeenCalledTimes(1);
1066-
1067-
ReactDOM.render(
1068-
<input value="foo" data-unrelated={true} onChange={onChange} />,
1069-
container,
1070-
);
1071-
expect(nodeValueSetter).toHaveBeenCalledTimes(1);
1072-
1073-
expect(() => {
1074-
ReactDOM.render(<input onChange={onChange} />, container);
1075-
}).toErrorDev(
1076-
'A component is changing a controlled input to be uncontrolled. This is likely caused by ' +
1077-
'the value changing from a defined to undefined, which should not happen. Decide between ' +
1078-
'using a controlled or uncontrolled input element for the lifetime of the component.',
1079-
);
1080-
expect(nodeValueSetter).toHaveBeenCalledTimes(1);
1081-
1082-
expect(() => {
1083-
ReactDOM.render(<input value={null} onChange={onChange} />, container);
1084-
}).toErrorDev(
1085-
'value` prop on `input` should not be null. Consider using an empty string to clear the ' +
1086-
'component or `undefined` for uncontrolled components.',
1087-
);
1088-
expect(nodeValueSetter).toHaveBeenCalledTimes(1);
1089-
1090-
expect(() => {
1091-
ReactDOM.render(<input value="" onChange={onChange} />, container);
1092-
}).toErrorDev(
1093-
' A component is changing an uncontrolled input to be controlled. This is likely caused by ' +
1094-
'the value changing from undefined to a defined value, which should not happen. Decide between ' +
1095-
'using a controlled or uncontrolled input element for the lifetime of the component.',
1096-
);
1097-
expect(nodeValueSetter).toHaveBeenCalledTimes(2);
1098-
1099-
ReactDOM.render(<input onChange={onChange} />, container);
1100-
expect(nodeValueSetter).toHaveBeenCalledTimes(2);
1101-
});
1102-
11031046
it('should not incur unnecessary DOM mutations for boolean properties', () => {
11041047
const container = document.createElement('div');
11051048
function onChange() {
@@ -1123,12 +1066,7 @@ describe('ReactDOMComponent', () => {
11231066
});
11241067

11251068
ReactDOM.render(
1126-
<input
1127-
type="checkbox"
1128-
onChange={onChange}
1129-
checked={true}
1130-
data-unrelated={true}
1131-
/>,
1069+
<input type="checkbox" onChange={onChange} checked={true} />,
11321070
container,
11331071
);
11341072
expect(nodeValueSetter).toHaveBeenCalledTimes(0);
@@ -1156,13 +1094,15 @@ describe('ReactDOMComponent', () => {
11561094
'using a controlled or uncontrolled input element for the lifetime of the component.',
11571095
);
11581096

1159-
expect(nodeValueSetter).toHaveBeenCalledTimes(2);
1097+
// TODO: Non-null values are updated twice on inputs. This is should ideally be fixed.
1098+
expect(nodeValueSetter).toHaveBeenCalledTimes(3);
11601099

11611100
ReactDOM.render(
11621101
<input type="checkbox" onChange={onChange} checked={true} />,
11631102
container,
11641103
);
1165-
expect(nodeValueSetter).toHaveBeenCalledTimes(3);
1104+
// TODO: Non-null values are updated twice on inputs. This is should ideally be fixed.
1105+
expect(nodeValueSetter).toHaveBeenCalledTimes(5);
11661106
});
11671107

11681108
it('should ignore attribute list for elements with the "is" attribute', () => {

packages/react-dom/src/__tests__/ReactDOMTextarea-test.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,6 @@ describe('ReactDOMTextarea', () => {
603603
ref={n => (node = n)}
604604
value="foo"
605605
onChange={emptyFunction}
606-
data-count={this.state.count}
607606
/>
608607
</div>
609608
);

0 commit comments

Comments
 (0)