3

Since change events are fired for input in some browsers only (namely IE) only when the focus is lost, my understanding is that the click event is a better way to listen for changes (see Getting value of HTML Checkbox from onclick/onchange events ).

However, when I only supply only the checked property with an onClick handler to a controlled input element in react, it complains with:

Warning: Failed prop type: You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.

What is the solution here? The react documentation seems to suggest using onChange, but that conflicts with the recommendations in the answer listed above.

6
  • @RahulSharma unfortunately, no - it is a controlled component in my case. Commented May 27, 2020 at 18:33
  • 2
    React wraps the browser's native events to provide a normalized interface. I can find one Github comment from 2015 which says the following: "... react uses the native click event to listen to user interaction with the radio, and then calls the onchange for the input. The reason for this (at least according to the comment in the code) is because IE8 does not fire the change event until blur ..." - so it sounds like this may already be handled. Have you tried? Commented May 27, 2020 at 18:40
  • What issue are you experiencing specifically with using change such as the react based answer in the question you posted in your question? stackoverflow.com/a/56632316/5059657 Commented May 27, 2020 at 18:41
  • 1
    Looking at React's code, it looks like to me that the edge case with IE which you mentioned is already handled, and that onChange would behave like you would expect on a modern browser. I would just use onChange instead of worrying about it yourself unless you can test it yourself. Commented May 27, 2020 at 18:48
  • 1
    Sure, give me a second! Commented May 27, 2020 at 18:50

1 Answer 1

3

React provides a cross-browser wrapper called SyntheticEvent to provide a normalized interface to events, but the documentation doesn't explicitly state which cases are or are not handled. Regarding the edge case with IE, this Github comment from 2015 suggests that it's already handled:

... react uses the native click event to listen to user interaction with the radio, and then calls the onchange for the input. The reason for this (at least according to the comment in the code) is because IE8 does not fire the change event until blur, so in order to be 'compatible' with IE8, the click event is used.

Looking at React's source, to me it strongly looks like this indeed is the case:

function shouldUseClickEvent(elem) {
  // Use the `click` event to detect changes to checkbox and radio inputs.
  // This approach works across all browsers, whereas `change` does not fire
  // until `blur` in IE8.
  const nodeName = elem.nodeName;
  return (
    nodeName &&
    nodeName.toLowerCase() === 'input' &&
    (elem.type === 'checkbox' || elem.type === 'radio')
  );
}

So I would just use onChange like you would on a modern browser, and worry about doing it yourself (or even opening a new issue in React's repo) if you find the behavior to differ on IE.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.