'Type text into a React input using javascript (Tampermonkey script)?
I'm trying to make a Tampermonkey script that'll automatically enter text into some form input fields.
Normally, you can do this with just:
myElement.value = "my new text"
Problem is, this form is using React, and I can't directly change the value, since it doesn't set the React state.. How can I enter my desired data into these React components in my Tampermonkey script?
Solution 1:[1]
The answer could be found there https://github.com/facebook/react/issues/11488#issuecomment-347775628
let input = someInput;
let lastValue = input.value;
input.value = 'new value';
let event = new Event('input', { bubbles: true });
// hack React15
event.simulated = true;
// hack React16 ?????descriptor??value???????
let tracker = input._valueTracker;
if (tracker) {
tracker.setValue(lastValue);
}
input.dispatchEvent(event);
Solution 2:[2]
React doesn't expose component instances, so they aren't reachable without tampering an application on initialization, if this is possible.
Input values should be changed like they would be with vanilla JavaScript, by emitting DOM events.
React provides utility library that has helper functions to do that.
Here's an example. An input:
<input id="input" value={this.state.name} onChange={e => this.setState({ name: e.target.value })} />
And user script that runs after React application initialization:
import { Simulate } from 'react-dom/test-utils';
const input = document.getElementById('input');
input.value = 'Foo';
Simulate.change(input);
Solution 3:[3]
There's some good answers here, but none that work with TextArea. Here's a generic method stolen from another SO post which handles more cases:
const inputTypes = [
window.HTMLInputElement,
window.HTMLSelectElement,
window.HTMLTextAreaElement,
];
export const triggerInputChange = (node, value = '') => {
// only process the change on elements we know have a value setter in their constructor
if ( inputTypes.indexOf(node.__proto__.constructor) >-1 ) {
const setValue = Object.getOwnPropertyDescriptor(node.__proto__, 'value').set;
const event = new Event('input', { bubbles: true });
setValue.call(node, value);
node.dispatchEvent(event);
}
};
Solution 4:[4]
class HelloWorld extends React.Component{
constructor(props){
super(props);
this.state = {firstname: ''};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e){
this.setState({firstname: e.target.value})
}
render(){
return(<div><input id="firstname" type=text onChange={(e) =>this.handleChange()} value={this.state.firstname} ></div>)
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | fengxing |
Solution 2 | Estus Flask |
Solution 3 | Dr-Bracket |
Solution 4 | abhishek |