MusicBrainz userscripts tips and tricks

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:


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.

10 Likes