Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onChange not firing on controlled input element when value is updated #8971

Closed
pudgereyem opened this issue Feb 9, 2017 · 6 comments
Closed

Comments

@pudgereyem
Copy link

I've found what to me appears as a bug.

Bug

When a controlled input element changes by updating it's value, onChange isn't called.

Reproduction

I made a codepen that illustrates the problem; http://codepen.io/pudgereyem/live/bgmvOq

Expected behaviour

I expect that onChange gets called, since the <input/> did change, and the world of React is by nature very much "controlled".

This is written in the docs and also mentioned in various threads such as #8550 (comment) and #8696 (comment).

My problem

The fact that the inputs onChange function not gets called is a problem to me, because I need to do logic (such as validation) when the inputs have changed.

Comments

  • I tried using onInput also, but it doesn't get called either
@pudgereyem pudgereyem changed the title onChange not firing on controlled input element onChange not firing on controlled input element when value is updated Feb 9, 2017
@eduardbme
Copy link

eduardbme commented Feb 9, 2017

It actually works for me, every time I change the input field I see the 'CHANGE' text inside console.
The problem why your input is always empty is that you didn't dispatch any action to change firstName inside props, except the click button.

you can check my pen http://codepen.io/eduardb/pen/zNmmRN with fix

@pudgereyem
Copy link
Author

pudgereyem commented Feb 9, 2017

Hi @eduardbcom, yeah of that I know. I guess my example wasn't 100% clear. What you should try doing is to click the button and watch for the 'CHANGE' inside the console. You don't get one when you are updating the value if you are not touching the input.

I'll update my codepen so this is more clear by adding the functionality you thought was missing.

EDIT: I've now updated the Codepen to make it more clear that the problem is when when you are trying to update the <input/> by "just passing" a new value to it.

@aweary
Copy link
Contributor

aweary commented Feb 9, 2017

Thanks for the report @pudgereyem, the example was really useful! This is expected behavior. The onChange event handler is meant to act like a typical event handler does, meaning its only invoked when the DOM dispatches the appropriate event. Although we treat onChange as a special case by changing its behavior to better match user expectations, it's still meant to be a standard event handler.

Check out this example that uses plain JavaScript:

var input = document.getElementById('input')

// This is only called when the input value
// is changed via the DOM, not when its changed
// programmatically using input.value
input.onchange = (e) => {
  window.alert(e.target.value)
}

setTimeout(() => {
  input.value = "changed"
}, 1000)

No change event is fired when input.value is updated, as there was technically no change event. This mirrors what React is doing. I see how it might be useful for React to invoke onChange whenever it detects that value has changed, but as of now that's not the expected behavior.

The fact that the inputs onChange function not gets called is a problem to me, because I need to do logic (such as validation) when the inputs have changed.

If the value is coming from props then you can always check the new value in componentWillReceiveProps

@eduardbme
Copy link

I can just add that you can use refs to emit change event by hand.

@pudgereyem
Copy link
Author

@aweary Thanks alot for the fast response.

I see how it might be useful for React to invoke onChange whenever it detects that value has changed, but as of now that's not the expected behavior.

Got it! Yes, it's an interesting discussion I think. I understand that it's now only meant to be a standard event handler. However, the input did change, so it would be neat if onChange would trigger also.

@eduardbcom yes I know, but thanks for adding that!

@pudgereyem
Copy link
Author

pudgereyem commented Feb 9, 2017

Hi @aweary and @eduardbcom,

Here is a new pen with a solution to my problem where I manually trigger onChange handler when input's value is updated: http://codepen.io/pudgereyem/live/OWBrdv

Achieved using componentWillReceiveProps as suggested by @aweary. Closing the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants