私は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
});
React Doc によると、onKeyPress
ではなくonKeyUp
やonChange
のようなキーボードイベントを聞くことができます。
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を使ったコードです。
class Input extends React.Component {
_handleKeyDown = (e) => {
if (e.key === 'Enter') {
console.log('do validate');
}
}
render() {
return <input type="text" onKeyDown={this._handleKeyDown} />
}
}
これが jsfiddle です。
入力フィールドに直接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()
}
}}
/>
Enter を押すと、フォームコントロール(入力)にフォーカスが当たって(入力ではなく)通常submit
(onSubmit)イベントが発生するので、this.handleInput
をフォームonSubmitにバインドできます。
あるいは、フォーカスが削除されたときに発生するblur
のinput
(onBlur)イベントにバインドすることもできます(例えば、フォーカスを取得できる次の要素へのタブ移動)。
あなたは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>
);
}
}
反応したユーザー、これが完全性に対する答えです。
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')
);
このような小さなラッパー関数を書くこともできます。
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)}/>