Use native input value setter to bypass React
Have you noticed recently that all of a sudden, your input.value = "toto"
are now ignored?
The input
and textarea
tags (and maybe also select
?) that fall in the scope of some React hydrate stuff, have their .value
setter hijacked by React.
So you cannot set value any more.
I mean, it is set to your new value, but then it is reverted within the next milliseconds.
What you have to do now is to force the use of the genuine .value
setter, to ignore the React modified .value
setter.
Replace:
input1.value = "toto";
input2.value = "tutu";
textarea.value = "haha";
By:
// use native input value setter to bypass React
var nativeInputValueSetter = Object.getOwnPropertyDescriptor(self.HTMLInputElement.prototype, "value").set;
// window and self are interchangeable, I'm used to use self, but the example I found uses window
var nativeTextareaValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set;
nativeInputValueSetter.call(input1, "toto");
nativeInputValueSetter.call(input2, "tutu");
nativeTextareaValueSetter.call(textarea, "haha");
It’s crazy, isn’t it?
And don’t forget to dispatch the change
event afterwards, as usual.
var event = document.createEvent("HTMLEvents");
event.initEvent("change", true, true);
input1.dispatchEvent(event);
// I have never tested if dispatching the same event
// on several elements does actually work
input2.dispatchEvent(event);
textarea.dispatchEvent(event);
Tested and approved fix for EASY_DATE.
Here is where I found this work-around when I had this bug:
- https://github.com/cypress-io/cypress/issues/647#issuecomment-335829482
- https://github.com/cypress-io/cypress/commit/4a56ca83b3b6e19ec57d10a8160f54f513e8f8ec#diff-53b7d619fa4613db14158a57ca69e8170a6f5e3d2271c61e762c801bff15552dR33-R46
- reactjs - What is the best way to trigger onchange event in react js - Stack Overflow
PS.
Dispatching the change
event is mandatory for all MB inputs, or maybe not but it’s a real safeguard to always do it.
On the other hand, I suggest you only use the force genuine value setter when it doesn’t work otherwise, because it makes the code more complex.
It is only necessary when the inputs are in a zone where some React hydrate occurs.