私はReactで構築されたクロールWebサイトを任されています。入力フィールドに入力して、ページにJavaScriptインジェクトを使用してフォームを送信しようとしています(SeleniumまたはモバイルのWebViewのいずれか)。これは他のすべてのサイト+テクノロジーの魅力のように機能しますが、Reactは実際の痛みのようです。
ここにサンプルコードがあります
var email = document.getElementById( 'email' );
email.value = '[email protected]';
DOM入力要素で値が変更されますが、Reactは変更イベントをトリガーしません。
私はReactを取得して状態を更新するためにさまざまな方法を試してきました。
var event = new Event('change', { bubbles: true });
email.dispatchEvent( event );
役立たず
var event = new Event('input', { bubbles: true });
email.dispatchEvent( event );
動かない
email.onChange( event );
動かない
Reactとのやり取りがとても難しくなったとは信じられません。ご協力をよろしくお願いします。
ありがとうございました
Reactは、テキストフィールドのinput
イベントをリッスンしています。
値を変更して入力イベントを手動でトリガーすると、reactのonChange
ハンドラーがトリガーされます。
class Form extends React.Component {
constructor(props) {
super(props)
this.state = {value: ''}
}
handleChange(e) {
this.setState({value: e.target.value})
console.log('State updated to ', e.target.value);
}
render() {
return (
<div>
<input
id='textfield'
value={this.state.value}
onChange={this.handleChange.bind(this)}
/>
<p>{this.state.value}</p>
</div>
)
}
}
ReactDOM.render(
<Form />,
document.getElementById('app')
)
document.getElementById('textfield').value = 'foo'
const event = new Event('input', { bubbles: true })
document.getElementById('textfield').dispatchEvent(event)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'></div>
この承認されたソリューションは、重複除外の入力と変更イベントの変更の結果、React> 15.6(React 16を含む))では機能しないようです。
あなたはReactここでの議論を見ることができます: https://github.com/facebook/react/issues/10135
ここで推奨される回避策: https://github.com/facebook/react/issues/10135#issuecomment-314441175
便宜上ここで再現:
の代わりに
input.value = 'foo';
input.dispatchEvent(new Event('input', {bubbles: true}));
あなたは使うでしょう
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);
}
}
その後
setNativeValue(input, 'foo');
input.dispatchEvent(new Event('input', { bubbles: true }));