Preact: Textareas are not initialized correctly during hydration

Created on 26 May 2020  路  2Comments  路  Source: preactjs/preact

I'm currently using Preact + Next.js with the configuration from nextjs-preact-demo. SSR with textareas seems to be breaking in Preact >=10.4.2.

Reproduction

CodeSandbox of last working version (10.4.1)
CodeSandbox of first broken version (10.4.2)

Expected Behavior

The textarea should be initialized with a value on page load.

Actual Behavior

The textarea is not initialized with a value on page load. The pre-rendered HTML seems to be the same between both 10.4.1 and 10.4.2, it just seems that Preact is not properly setting the textarea value during hydration.

beginner-friendly compat

Most helpful comment

Just checked with the HTML spec and the value attribute is indeed not valid for <textarea> elements:

https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element

So the output of preact-render-to-string is correct.

React seems to automatically render the content of props.value as children for <textarea> and we should be able to do the same in preact/compat.

To fix this we should add the aliasing to `preact/compat麓. This can be done by adding the necessary lines somewhere around here, where other React-specific props handling is done:

https://github.com/preactjs/preact/blob/5a1f9fbc32c2cb4ee5e946f6456d1579b53fb0c3/compat/src/render.js#L114-L131

All 2 comments

I took some time to investigate this, and it looks like this issue has existed for a while, the only reason it worked in 10.4.1 is because preact-compat exported render in place of hydrate (fixed in #2511).

The quickest hack would be to make an exception for textarea nodes when props are diffed during hydration: https://github.com/preactjs/preact/blob/51836c926a0817aa8357df89aca08b48cb913a30/src/diff/index.js#L384-L385

However, this doesn't address the underlying issue that

  1. preact-render-to-string generates the incorrect HTML <textarea value="foo"></textarea> instead of <textarea>foo</textarea>
  2. Preact will not properly hydrate <textarea>foo</textarea> if the value is set via the value prop rather than children.

Just checked with the HTML spec and the value attribute is indeed not valid for <textarea> elements:

https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element

So the output of preact-render-to-string is correct.

React seems to automatically render the content of props.value as children for <textarea> and we should be able to do the same in preact/compat.

To fix this we should add the aliasing to `preact/compat麓. This can be done by adding the necessary lines somewhere around here, where other React-specific props handling is done:

https://github.com/preactjs/preact/blob/5a1f9fbc32c2cb4ee5e946f6456d1579b53fb0c3/compat/src/render.js#L114-L131

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nopantsmonkey picture nopantsmonkey  路  3Comments

rajaraodv picture rajaraodv  路  3Comments

adriaanwm picture adriaanwm  路  3Comments

matthewmueller picture matthewmueller  路  3Comments

mizchi picture mizchi  路  3Comments