web-dev-qa-db-ja.com

Reactで作成された入力要素をプログラムで埋める方法は?

私は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とのやり取りがとても難しくなったとは信じられません。ご協力をよろしくお願いします。

ありがとうございました

17
Timo Kauranen

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>
10
Timo

この承認されたソリューションは、重複除外の入力と変更イベントの変更の結果、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 }));
11
meriial