Programmatically fill reactjs form

帅比萌擦擦* 提交于 2020-01-23 01:37:52

问题


I am writing an userscript and I can't manage to fill a form made by reactjs. My code:

document.querySelector("#id-username").value = "name@domain.xx";
// Attempt to notify framework using input event
document.querySelector("#id-username").dispatchEvent(new Event("input", {data:"name@domain.xx"}));
// Attempt to notify framework using change event
document.querySelector("#id-username").dispatchEvent(new Event("change"));
// This doesn't help either
document.querySelector("#id-username").dispatchEvent(new Event("blur"));
// Submit the form using button (it's AJAX form)
document.querySelector("fieldset div.wrap button").click();

I entered this code into developper tools console after loading the page. However the form ignores my programatical input:

The form can be found here. The purpose of my work is to automate login to given website. I provided the specific URL, but I expect generic solution to this problem (eg. using some reactjs API) that can be applied to any reactjs form. Other users might need this solution for writing automated tests for their sites.


回答1:


Event must be emmited to ReactJS to make it register the value. In particular, the input event. It is really important to ensure that the event bubbles - React JS has only one listener at the document level, rather than on the input field. I crafted the following method to set the value for input field element:

function reactJSSetValue(elm, value) {
    elm.value = value;
    elm.defaultValue = value;
    elm.dispatchEvent(new Event("input", {bubbles: true, target: elm, data: value}));
}



回答2:


For Chrome version 64, there is a workaround. Otherwise the event is being ignored.

See:https://github.com/facebook/react/issues/10135#issuecomment-314441175

(Full credit to fatfisz in the link)

Code

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

Usage

setNativeValue(textarea, 'some text');
// you must dispatch the input event, or the value will not update !!!
textarea.dispatchEvent(new Event('input', { bubbles: true }));


来源:https://stackoverflow.com/questions/42795059/programmatically-fill-reactjs-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!