web-dev-qa-db-ja.com

enterキーを押した後にonChangeイベントを呼び出す

私はBootstrapに不慣れで、この問題で立ち往生しています。入力フィールドがあり、1桁だけ入力するとすぐにonChangeの関数が呼び出されますが、整数が入力されたときにEnterキーを押すと呼び出されるようにします。検証機能についても同じ問題です。

var inputProcent = React.CreateElement(bootstrap.Input, {type: "text",
  //bsStyle: this.validationInputFactor(),
  placeholder: this.initialFactor,
  className: "input-block-level",
  onChange: this.handleInput,
  block: true,
  addonBefore: '%',
  ref:'input',
  hasFeedback: true
});
145
Bill Lumbert

React Doc によると、onKeyPressではなくonKeyUponChangeのようなキーボードイベントを聞くことができます。

var Input = React.createClass({
  render: function () {
    return <input type="text" onKeyDown={this._handleKeyDown} />;
  },
  _handleKeyDown: function(e) {
    if (e.key === 'Enter') {
      console.log('do validate');
    }
  }
});

更新:React.Componentを使う

これは同じことをするReact.Componentを使ったコードです。

class Input extends React.Component {
  _handleKeyDown = (e) => {
    if (e.key === 'Enter') {
      console.log('do validate');
    }
  }

  render() {
    return <input type="text" onKeyDown={this._handleKeyDown} />
  }
}

これが jsfiddle です。

307
wuct

入力フィールドに直接onKeyPressを使用できます。 onChange関数は入力フィールドが変更されるたびに状態値を変更し、Enterが押された後に関数search()を呼び出します。

<input
    type="text"
    placeholder="Search..."
    onChange={event => {this.setState({query: event.target.value})}}
    onKeyPress={event => {
                if (event.key === 'Enter') {
                  this.search()
                }
              }}
/>
27
Admir

Enter を押すと、フォームコントロール(入力)にフォーカスが当たって(入力ではなく)通常submit(onSubmit)イベントが発生するので、this.handleInputをフォームonSubmitにバインドできます。

あるいは、フォーカスが削除されたときに発生するblurinput(onBlur)イベントにバインドすることもできます(例えば、フォーカスを取得できる次の要素へのタブ移動)。

21
Luca

あなたはevent.keyを使うことができます

function Input(props) {
  return (
    <div>
      Input
      <input type="text" onKeyPress={props.onKeyPress}/>
    </div>
  )
}

class Form extends React.Component {
  constructor(props) {
    super(props)

    this.handleKeyPress = this.handleKeyPress.bind(this)
  }

  handleKeyPress(event) {
    if (event.key === 'Enter') {
      console.log('enter key pressed')
    }
  }

  render() {
    return (
      <section>
        <Input onKeyPress={this.handleKeyPress}/>
        <Output value={this.state.output}/>
      </section>
    );
  }
}
4
onmyway133

反応したユーザー、これが完全性に対する答えです。

React version 16.4.2

すべてのキーストロークについて更新するか、送信時にのみ値を取得します。コンポーネントへの重要なイベントの追加は機能しますが、公式文書で推奨されているように代替方法があります。

管理されていないコンポーネントと管理されていないコンポーネント

管理された

Docs - FormsおよびControlledコンポーネントから

HTMLでは、input、textarea、selectなどのフォーム要素は通常、独自の状態を維持し、ユーザー入力に基づいて更新します。 Reactでは、可変状態は通常コンポーネントのstateプロパティに保持され、setState()でのみ更新されます。

React状態を「単一の真実の源」にすることで、2つを組み合わせることができます。その後、フォームをレンダリングするReactコンポーネントは、その後のユーザー入力時にそのフォームで行われる処理も制御します。このようにReactによって値が制御される入力フォーム要素は、「制御対象コンポーネント」と呼ばれます。

管理対象コンポーネントを使用している場合は、値を変更するたびに状態を更新し続ける必要があります。これを実現するには、イベントハンドラをコンポーネントにバインドします。ドキュメントの例では、通常onChangeイベントです。

例:

1)コンストラクタ内でイベントハンドラをバインドする(値はstateのまま)

constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
}

2)ハンドラ関数を作成する

handleChange(event) {
    this.setState({value: event.target.value});
}

3)フォーム送信機能を作成する(値は州から取得されます)

handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
}

4)レンダリング

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" value={this.state.value} onChange={this.handleChange} />
    </label>
    <input type="submit" value="Submit" />
</form>

controlled componentsを使用すると、適切な状態を更新して維持するために、handleChange関数が常に起動されます。州は常に更新された値を持ち、フォームが送信されると、値は州から取得されます。フォームが非常に長い場合は、すべてのコンポーネントに対して関数を作成するか、すべてのコンポーネントの値の変更を処理する単純な関数を作成する必要があるため、これは問題になる可能性があります。

未制御

ドキュメント - 未制御コンポーネントから

ほとんどの場合、フォームを実装するために制御コンポーネントを使用することをお勧めします。管理対象コンポーネントでは、フォームデータはReactコンポーネントによって処理されます。代替手段は、フォームデータがDOM自体によって処理される、制御されていないコンポーネントです。

状態の更新ごとにイベントハンドラを作成するのではなく、制御されていないコンポーネントを作成するには、refを使用してDOMからフォーム値を取得します。

ここでの主な違いは、onChange関数ではなく、フォームのonSubmitを使って値を取得し、必要に応じて検証することです。

例:

1)イベントハンドラをバインドし、コンストラクタに入力するためのrefを作成します(値は状態を維持しません)。

constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();
}

2)フォーム送信機能を作成する(値はDOMコンポーネントから取得されます)

handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);
    event.preventDefault();
}

3)レンダリング

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" ref={this.input} />
    </label>
    <input type="submit" value="Submit" />
</form>

uncontrolled componentsを使用する場合、handleChange関数をバインドする必要はありません。フォームが送信されると、値はDOMから取得され、この時点で必要な検証が行われます。入力コンポーネントに対してもハンドラ関数を作成する必要はありません。

あなたの問題

さて、あなたの問題のために:

...整数が入力されたときにEnterキーを押すと呼び出されるようにします。

これを達成したい場合は、制御されていないコンポーネントを使用してください。必要でなければonChangeハンドラを作成しないでください。 enterキーがフォームを送信し、handleSubmit関数が起動されます。

あなたがする必要がある変更:

要素内のonChange呼び出しを削除します。

var inputProcent = React.CreateElement(bootstrap.Input, {type: "text",
    //    bsStyle: this.validationInputFactor(),
    placeholder: this.initialFactor,
    className: "input-block-level",
    // onChange: this.handleInput,
    block: true,
    addonBefore: '%',
    ref:'input',
    hasFeedback: true
});

送信フォームを処理して入力を検証します。フォームの送信機能で要素から値を取得して検証する必要があります。必ずコンストラクタ内で自分の要素への参照を作成してください。

  handleSubmit(event) {
      // Get value of input field
      let value = this.input.current.value;
      event.preventDefault();
      // Validate 'value' and submit using your own api or something
  }

制御されていないコンポーネントの使用例

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    // bind submit function
    this.handleSubmit = this.handleSubmit.bind(this);
    // create reference to input field
    this.input = React.createRef();
  }

  handleSubmit(event) {
    // Get value of input field
    let value = this.input.current.value;
    console.log('value in input field: ' + value );
    event.preventDefault();
    // Validate 'value' and submit using your own api or something
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

ReactDOM.render(
  <NameForm />,
  document.getElementById('root')
);
1
c-chavez

このような小さなラッパー関数を書くこともできます。

const onEnter = (event, callback) => event.key === 'Enter' && callback()

それからあなたの入力でそれを消費する

<input 
    type="text" 
    placeholder="Title of todo" 
    onChange={e => setName(e.target.value)}
    onKeyPress={e => onEnter(e, addItem)}/>
0
David Alsh