Home > database >  Handle real `change` event in React
Handle real `change` event in React

Time:01-29

In javascript input has change event that in case of type="number" occures when either the input looses its focus or user uses step up or step down functionality, but not on the normal typing.

document.querySelector("input").addEventListener("change", e => {
  console.log(e.type, e.target.value)
})
<input type="number" step="0.1"> <button>&nbsp;</button>

But when I'm using react, it replaces change event by input event which occurs on typing too:

function App() {
  const [val, setVal] = React.useState("")
  
  function onChange(e) {
    console.log(e.type, e.nativeEvent.type, e.target.value)
    setVal(e.target.value)
  }
  
  return (
    <React.Fragment>
     <input type="number" step="0.1" value={val} onChange={onChange} />
     {" "}
     <button>&nbsp;</button>
    </React.Fragment>
  )
}

ReactDOM.render(<App />, document.querySelector("main"))
<script crossorigin src="//unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="//unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<main></main>

I need to handle normal change event that does not occur on typing.
How can I do that in react?

PS: Button in the snippects is a place where you can tab to from the input.

CodePudding user response:

Here's a way to intercept all the input types of interest, link to codesandbox -> https://codesandbox.io/s/summer-resonance-58n15?file=/src/App.js:

function App() {
  const [val, setVal] = React.useState("");

  function onChange(e) {
    if (e.nativeEvent.inputType === "insertText") {
      console.log("input");
    } else if (e.nativeEvent.inputType === undefined) {
      if (e.target.value > val) {
        console.log("step up");
      } else {
        console.log("step down");
      }
    } else if (e.nativeEvent.inputType === "deleteContentBackward") {
      console.log("deleting");
    }
    setVal(e.target.value);
  }

  return (
    <React.Fragment>
      <input type="number" step="0.1" value={val} onChange={onChange} />{" "}
      <button>&nbsp;</button>
    </React.Fragment>
  );
}

CodePudding user response:

You can simply create a ref of your input and create your eventListener as you do in Javascript :

import React from "react";
import { render } from "react-dom";

const App = () => {
  const inputRef = React.useRef();

  React.useEffect(() => {
    inputRef.current.addEventListener('change', (e) => console.log(e.target.value))
  })

  return (
    <div>
      <input ref={inputRef} type="number" />
    </div>
  );
};

render(<App />, document.getElementById("root"));
  •  Tags:  
  • Related