How to programmatically fill input elements built with React?

This accepted solution appears not to work in React > 15.6 (including React 16) as a result of changes to de-dupe input and change events.

You can see the React discussion here: https://github.com/facebook/react/issues/10135

And the suggested workaround here:
https://github.com/facebook/react/issues/10135#issuecomment-314441175

Reproduced here for convenience:

Instead of

input.value="foo";
input.dispatchEvent(new Event('input', {bubbles: true}));

You would use

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);
  }
}

and then

setNativeValue(input, 'foo');
input.dispatchEvent(new Event('input', { bubbles: true }));

Leave a Comment