Skip to content

dispatchEvent on input/textarea is ignored #10135

Closed
@fatfisz

Description

@fatfisz
Contributor

Do you want to request a feature or report a bug?
bug

What is the current behavior?
The dispatchEvent method has no effect on input/textarea elements.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template: https://jsfiddle.net/84v837e9/).
v. 15.5.4: https://jsfiddle.net/c8tp5mqf/ (working)
v. 15.6.1: https://jsfiddle.net/6bv1581z/ (not working)

What is the expected behavior?
The dispatchEvent method results in an event being handled.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
I'm using the latest Chrome browser. This has worked in 15.5.x, stopped working in 15.6.0 and is still not working in 15.6.1.


Usecase for this: some old tests that I'd happily remove, but have to support for now.

Activity

gaearon

gaearon commented on Jul 11, 2017

@gaearon
Collaborator
gaearon

gaearon commented on Jul 11, 2017

@gaearon
Collaborator

Oops, I meant to cc @jquense

jquense

jquense commented on Jul 11, 2017

@jquense
Contributor

Yes this is expected and unavoidable to some extent. React dedupe change and input events so they don't fire too often, in this case even tho you intentionally want to trigger the event react is swallowing it because it the input value has not changed. you can use the SimulateNative helper to get the behavior your looking for. Tho that will break again in v16

gaearon

gaearon commented on Jul 11, 2017

@gaearon
Collaborator

What's the workaround?

gaearon

gaearon commented on Jul 11, 2017

@gaearon
Collaborator

I guess this is grey area and unclear if we supported this. As @jquense mentioned you can use SimulateNative in the meantime. After 16, feel free to file a new issue and we'll look at other ways of handling this.

jquense

jquense commented on Jul 11, 2017

@jquense
Contributor

cypress-io/cypress#536 from an additional use case affected similarly. They outline their long term "workaround" as well.

I do think this falls into a gray area, complete transparent DOM interoperability is always nice but hard to do and potentially limiting give Reacts model for targeting and it :/

fatfisz

fatfisz commented on Jul 11, 2017

@fatfisz
ContributorAuthor

@jquense Btw. this happens no matter if the value is changed or not - I probably should've included that info in this issue.

I understand that this is unexpected (the event should not be swallowed by React if the value has changed), so I'm including an updated example: https://jsfiddle.net/6bv1581z/1/

fatfisz

fatfisz commented on Jul 11, 2017

@fatfisz
ContributorAuthor

I'll need some time to process the use case in cypress (esp. the part about the setters - don't really know what the spec says about this), so I'm not strongly opinionated for now.

In any case, the simulated thing seems to be working for now and the code that's using it waits for a rewrite, so that might be turned into a non-issue for me.

I'm just wondering - won't this affect the ability to make integration tests for React-based apps using the DOM api?

Sorry if that's all answered in the linked thread, I have yet to connect the dots.

fatfisz

fatfisz commented on Jul 11, 2017

@fatfisz
ContributorAuthor

Just leaving a solution for future reference (checked in Edge 15, IE 11, FF 53, Chrome 59):

function setNativeValue(element, value) {
  const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
  const prototype = Object.getPrototypeOf(element);
  const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
  
  if (valueSetter && valueSetter !== prototypeValueSetter) {
  	prototypeValueSetter.call(element, value);
  } else {
    valueSetter.call(element, value);
  }
}

Use it like so:

setNativeValue(textarea, 'some text');
textarea.dispatchEvent(new Event('input', { bubbles: true }));
jquense

jquense commented on Jul 11, 2017

@jquense
Contributor

Btw. this happens no matter if the value is changed or not - I probably should've included that info in this issue.

Yes, i also left that bit off because its a bit hard to explain, but React tracks manual DOMNode.value changes as well, so when you do input.value ='foo' and then dispatch a change event React sees two discreet moments there, the first change and then the change via the event, so when your input event fires the value is still 'foo' and React says "I already know about that that value so this must be a duplicate"

I'm just wondering - won't this affect the ability to make integration tests for React-based apps using the DOM api?

It shouldn't, if you are using something like Selenium, which fires "real" events when you ask it too, vs "fake" ones we can fire in the DOM. Comparative tools like Cypress or nightmare, etc should use workarounds that mimic the real browsers behavior so if something breaks (as in this case) it was more of a bug in Cypress :)

40 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @jquense@tkrotoff@gaearon@gmattie@kentcdodds

        Issue actions

          dispatchEvent on input/textarea is ignored · Issue #10135 · facebook/react