Search code examples
javascripthtmlreactjsonchange

Why onchange behaves differently on React vs HTML


First Example

HTML: in the example below the console.log() is triggered when the text box is modified and enter is pressed.

<input type="text" onchange="console.log(1)" />

React: in the example below the console.log() is triggered only one time, when page is loaded.

function App() {
  return (
    <input type="text" onChange={console.log(1)} />
  );
}

export default App;

Second example

In this example I wrap the console.log() inside a function.

HTML: Same as before. The console.log() is triggered when the text box is modified and enter is pressed.

<script>
    const foo = () => {console.log(1)}
</script>
<input type="text" onchange="foo()" />

React: in the example below the console.log() is triggered on the fly. Press enter is not needed and every input triggers console.log().

function App() {
  const foo = () => {console.log(1)}
  return (
    <input type="text" onChange={foo} />
  );
}

export default App;

Solution

  • This is covered in the React tutorial:

    With JSX you pass a function as the event handler, rather than a string.

    When you say onChange={console.log(1)} the JavaScript expression console.log(1) is evaluated immediately (and on every render of the component) and the return value is assigned as the event handler (since the return value from console.log is undefined (which is not a function), this is useless).


    in the example below the console.log() is triggered on the fly.

    See the description of onChange in the documentation:

    We intentionally do not use the existing browser behavior because onChange is a misnomer for its behavior and React relies on this event to handle user input in real time.