Preact: 10.0.0-alpha.2 - <input onChange> normalization?

Created on 15 Mar 2019  路  8Comments  路  Source: preactjs/preact

Calling setState in a onChange callback of <input type="text"> doesn't update that input as in React's controlled component pattern.

I use this to give feedback to the user when an invalid value is entered by resetting it to the last valid value.

Example:
Typing something into the form and pressing Enter correctly updates the state.
Entering XYZ and pressing Enter doesn't update the state but also doesn't reset the input element.

import { Component, render } from "preact";

class App extends Component {
  state = { text: "X" };

  render() {
    return (
      <div>
        {this.state.text}
        <br />
        <input
          type="text"
          value={this.state.text}
          onChange={e => {
            if (e.target.value !== "XYZ") {
              this.setState({
                text: e.target.value
              });
            } else {
              this.setState({
                text: this.state.text
              });
            }
          }}
        />
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

Works with "preact": "^8.0.0":
Codesandbox: https://codesandbox.io/s/kmn5400y2v

wontfix

Most helpful comment

This was indeed fixed together with #1324 馃帀

All 8 comments

The problem is that setState isn't getting called. The component is being treated as an uncontrolled component for aslong as you are typing than when the event captures/bubbles the onChange gets called.

Does not work with preact 8 either for me: https://codesandbox.io/s/5n9ny5pvx

The problem is that setState isn't getting called

It is.

Preact 8:
Pressing enter causes the Z to vanish.
Preact 8

Preact X:
I'm repeatedly pressing enter after typing Z. The input doesn't change
Preact 10

Oh I thought you meant without pressing enter, my bad there. Well yes something is holding it off. Will try to look into this.

Preact does not normalize onChange to use onInput behaviour. If you include preact/compat in your project it will do so, but the default is to treat events as they exist in the DOM. The reason it worked in some Preact 8 apps was because compat patched it for all VNodes rather than only patching React.createElement.

In general, it's recommended to use onInput for this reason:
https://codesandbox.io/s/ll0n7j27nz

Preact does not normalize onChange to use onInput behaviour

By "onInput behaviour" you mean "runs on every keystroke"? That's not the issue.

Please try entering "XYZ" in this codesandbox: https://codesandbox.io/s/qzjq7pkq3q
It won't let you (using Preact 8). That's what I want to achieve.

Or maybe I misunderstood your comment

After reading this it looks like this is a duplicate of #1324. The state is set correctly but preact X doesn't diff the vnodes value with the inputs dom value.

After reading this it looks like this is a duplicate of #1324.

Looks very similar, but if I add a button and change the state there, it works. Not sure if these two issues caused by the exact same underlying problem

This was indeed fixed together with #1324 馃帀

Was this page helpful?
0 / 5 - 0 ratings