Skip to content

Commit

Permalink
Fix hydrating textarea with value prop (#3891)
Browse files Browse the repository at this point in the history
* Fix hydrating textarea with value prop

* Golf setting value
  • Loading branch information
andrewiggins committed Feb 14, 2023
1 parent dec4d42 commit b99c91c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
19 changes: 19 additions & 0 deletions compat/src/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,25 @@ options._render = function(vnode) {
currentComponent = vnode._component;
};

const oldDiffed = options.diffed;
/** @type {(vnode: import('./internal').VNode)} */
options.diffed = function(vnode) {
if (oldDiffed) {
oldDiffed(vnode);
}

const props = vnode.props;
const dom = vnode._dom;
if (
dom != null &&
vnode.type === 'textarea' &&
'value' in props &&
props.value !== dom.value
) {
dom.value = props.value == null ? '' : props.value;
}
};

// This is a very very private internal function for React it
// is used to sort-of do runtime dependency injection. So far
// only `react-relay` makes use of it. It uses it to read the
Expand Down
18 changes: 17 additions & 1 deletion compat/test/browser/textarea.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React, { render, useState } from 'preact/compat';
import React, { render, hydrate, useState } from 'preact/compat';
import ReactDOMServer from 'preact/compat/server';
import { setupScratch, teardown } from '../../../test/_util/helpers';
import { act } from 'preact/test-utils';

describe('Textarea', () => {
/** @type {HTMLElement} */
let scratch;

beforeEach(() => {
Expand All @@ -19,6 +21,20 @@ describe('Textarea', () => {
expect(scratch.firstElementChild.value).to.equal('foo');
});

it('should hydrate textarea value', () => {
function App() {
return <textarea value="foo" />;
}

scratch.innerHTML = ReactDOMServer.renderToString(<App />);
expect(scratch.firstElementChild.value).to.equal('foo');
expect(scratch.innerHTML).to.be.equal('<textarea>foo</textarea>');

hydrate(<App />, scratch);
expect(scratch.firstElementChild.value).to.equal('foo');
expect(scratch.innerHTML).to.be.equal('<textarea></textarea>');
});

it('should alias defaultValue to children', () => {
// TODO: IE11 doesn't update `node.value` when
// `node.defaultValue` is set.
Expand Down

0 comments on commit b99c91c

Please sign in to comment.