我是 Bootstrap 的新手,并且遇到了这个问题。我有一个输入字段,只要我输入一个数字,就会调用 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
这是使用 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。
更新 2:使用功能组件
const Input = () => {
const handleKeyDown = (event) => {
if (event.key === 'Enter') {
console.log('do validate')
}
}
return <input type="text" onKeyDown={handleKeyDown} />
}
您可以直接在输入字段上使用 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()
}
}}
/>
onKeyPress={this.yourFunc}
否则将在每次渲染时重新创建胖箭头函数。
onKeyPress={event => event.key === 'Enter' && this.search()}
在表单控件(输入)中按 Enter 通常会在表单上触发 submit
(onSubmit
) 事件。考虑到您可以通过这种方式处理它(如果您只有一个输入,则可以选择提交按钮):
常量 { useState } = 反应;函数 App() { const [text, setText] = useState(""); const [提交,setSubmitted] = useState('');函数handleChange(e) { setText(e.target.value); } 函数句柄提交(e) { e.preventDefault();设置提交(文本);设置文本(“”); } return (
隐式表单提交(Enter 上的 submit
事件)在以下情况下执行:
有一个提交按钮
没有提交按钮,但只有一个输入
更多关于它here。
或者,您可以将处理程序绑定到 input
上的 blur
(onBlur
) 事件,该事件在移除焦点时发生(例如,跳到下一个可以获得焦点的元素)。
onKeyPress
干净得多。
event.target.value
不可用
您可以使用 event.key
function Input({onKeyPress}) { return (
反应用户,这是完整性的答案。
反应版本 16.4.2
您要么想为每次击键更新,要么只在提交时获取值。向组件添加关键事件是可行的,但官方文档中推荐了其他替代方法。
受控与非受控组件
受控
从 Docs - Forms and Controlled components:
在 HTML 中,input、textarea 和 select 等表单元素通常会维护自己的状态并根据用户输入进行更新。在 React 中,可变状态通常保存在组件的 state 属性中,并且只能使用 setState() 进行更新。我们可以通过使 React 状态成为“单一事实来源”来将两者结合起来。然后,呈现表单的 React 组件还控制后续用户输入在该表单中发生的情况。以这种方式由 React 控制其值的输入表单元素称为“受控组件”。
如果您使用受控组件,则必须为值的每次更改保持状态更新。为此,您将事件处理程序绑定到组件。在文档的示例中,通常是 onChange 事件。
例子:
1)在构造函数中绑定事件处理程序(值保持在状态)
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>
如果您使用 受控 组件,您的 handleChange
函数将始终被触发,以便更新并保持正确的状态。状态将始终具有更新的值,并且当提交表单时,该值将从状态中获取。如果您的表单很长,这可能是一个缺点,因为您必须为每个组件创建一个函数,或者编写一个简单的函数来处理每个组件的值变化。
不受控制
从Docs - Uncontrolled component
在大多数情况下,我们建议使用受控组件来实现表单。在受控组件中,表单数据由 React 组件处理。另一种方法是不受控制的组件,其中表单数据由 DOM 本身处理。要编写不受控制的组件,而不是为每个状态更新编写事件处理程序,您可以使用 ref 从 DOM 获取表单值。
这里的主要区别是您不使用 onChange
函数,而是使用表单的 onSubmit
来获取值,并在必要时进行验证。
例子:
1)绑定事件处理程序并在构造函数中为输入创建引用(状态中没有保留值)
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>
如果您使用 不受控 组件,则无需绑定 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)}/>
阻止 Enter 在输入中提交表单的示例,在我的情况下,它是谷歌地图位置自动完成输入
<input
ref={addressInputRef}
type="text"
name="event[location]"
className="w-full"
defaultValue={location}
onChange={(value) => setLocation(value)}
onKeyDown={(e) => {
if (e.code === "Enter") {
e.preventDefault()
}
}}
/>
我更喜欢 onKeyUp
因为它仅在释放键时触发。另一方面,如果由于某种原因用户按住键,onKeyDown
将触发多次。例如,当侦听“按下”Enter
键以发出网络请求时,您不希望它多次触发,因为它可能很昂贵。
// handler could be passed as a prop
<input type="text" onKeyUp={handleKeyPress} />
handleKeyPress(e) {
if (e.key === 'Enter') {
// do whatever
}
}
此外,请远离 keyCode
,因为它会在一段时间内被弃用。
下面是一个使用基于类的组件的常见用例:父组件提供回调函数,子组件渲染输入框,当用户按下回车时,我们将用户的输入传递给父组件。
class ParentComponent extends React.Component {
processInput(value) {
alert('Parent got the input: '+value);
}
render() {
return (
<div>
<ChildComponent handleInput={(value) => this.processInput(value)} />
</div>
)
}
}
class ChildComponent extends React.Component {
constructor(props) {
super(props);
this.handleKeyDown = this.handleKeyDown.bind(this);
}
handleKeyDown(e) {
if (e.key === 'Enter') {
this.props.handleInput(e.target.value);
}
}
render() {
return (
<div>
<input onKeyDown={this.handleKeyDown} />
</div>
)
}
}
const [value, setValue] = useState("");
const handleOnChange = (e) => {
setValue(e.target.value);
};
const handleSubmit = (e) => {
e.preventDefault();
addTodoItem(value.trim());
setValue("");
};
return (
<form onSubmit={handleSubmit}>
<input value={value} onChange={handleOnChange}></input>
</form>
);
//You can use onkeyup directly on input field
const inputField = document.querySelector("input");
inputField.addEventListener("keyup", e => {
if (e.key == "Enter") {
console.log("hello");
}
});
不定期副业成功案例分享
onBlur
事件。<input ref='reference' onKeyPress={(e) => {(e.key === 'Enter' ? doSomething(this.refs.reference.value) : null)}} />
ref
。<input onKeyPress={e => doSomething(e.target.value)}
就足够了。onKeyPress
时都创建一个新函数。这是一个微妙的性能改进。