Skip to content

Commit cae8d3a

Browse files
authored
Fix migrations when we have defaultValue or value on a textarea (#5081)
1 parent 4dc9b50 commit cae8d3a

2 files changed

Lines changed: 19 additions & 2 deletions

File tree

src/diff/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,10 @@ function diffElementNodes(
474474
}
475475
} else {
476476
// If excessDomChildren was not null, repopulate it with the current element's children:
477-
excessDomChildren = excessDomChildren && slice.call(dom.childNodes);
477+
excessDomChildren =
478+
nodeType == 'textarea' && newProps.defaultValue != NULL
479+
? NULL
480+
: excessDomChildren && slice.call(dom.childNodes);
478481

479482
// If we are in a situation where we are not hydrating but are using
480483
// existing DOM (e.g. replaceNode) we should read the existing DOM
@@ -562,7 +565,7 @@ function diffElementNodes(
562565
}
563566

564567
// As above, don't diff props during hydration
565-
if (!isHydrating) {
568+
if (!isHydrating || nodeType == 'textarea') {
566569
i = 'value';
567570
if (nodeType == 'progress' && inputValue == NULL) {
568571
dom.removeAttribute('value');

test/browser/hydrate.test.jsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,20 @@ describe('hydrate()', () => {
6767
expect(scratch.firstChild.value).to.equal('foo');
6868
});
6969

70+
// Test for preactjs/preact#5080
71+
it('should respect textarea defaultValue in hydrate', () => {
72+
scratch.innerHTML = '<textarea>foo</textarea>';
73+
hydrate(<textarea defaultValue="foo" />, scratch);
74+
expect(scratch.firstChild.value).to.equal('foo');
75+
expect(scratch.firstChild.defaultValue).to.equal('foo');
76+
});
77+
78+
it('should respect textarea value in hydrate', () => {
79+
scratch.innerHTML = '<textarea>foo</textarea>';
80+
hydrate(<textarea value="foo" />, scratch);
81+
expect(scratch.firstChild.value).to.equal('foo');
82+
});
83+
7084
it('should respect defaultChecked in hydrate', () => {
7185
scratch.innerHTML = '<input checked="true">';
7286
hydrate(<input defaultChecked />, scratch);

0 commit comments

Comments
 (0)