按Enter键后调用onChange事件

我是新的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
});
515817 次浏览

在表单控件(输入)中按输入通常会触发表单上的submit (onSubmit)事件。考虑到你可以这样处理它(如果你只有一个输入,提交按钮是可选的):

const { useState } = React;


function App() {
const [text, setText] = useState("");
const [submitted, setSubmitted] = useState('');


function handleChange(e) {
setText(e.target.value);
}


function handleSubmit(e) {
e.preventDefault();
setSubmitted(text);
setText("");
}


return (
<div>
<form onSubmit={handleSubmit}>
<input type="text" value={text} onChange={handleChange} />
<input type="submit" value="add" />
</form>
submitted: {submitted}
</div>
);
}


ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
<div id="root"></div>

隐式表单提交(输入上的submit事件)在以下情况下执行:

  • 有一个提交按钮
  • 没有提交按钮,但只有一个输入

更多关于它在这里

或者,你可以将你的处理程序绑定到input上的blur (onBlur)事件,该事件发生在焦点被移除时(例如,选项卡到下一个可以获得焦点的元素)。

根据反应医生,你可以监听键盘事件,比如onKeyPressonKeyUp,而不是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。组件

下面是使用React的代码。组件,它做同样的事情

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()
}
}}
/>

你可以使用event.key

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


class Form extends React.Component {
state = {value:""}


handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.setState({value:e.target.value})
}
}


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


ReactDOM.render(
<Form />,
document.getElementById("react")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>

React用户,这里有一个完整的答案。

React 16.4.2版

您要么希望为每次击键更新,要么只在提交时获取值。将关键事件添加到组件中是有效的,但是在官方文档中有推荐的替代方法。

受控组件与不受控组件

控制

文档-表单和受控组件:

在HTML中,表单元素,如input, textarea和select 维护它们自己的状态并根据用户输入更新它。在反应, 可变状态通常保存在组件的state属性中,

我们可以将这两者结合起来,使React状态成为“单一源” 的真相”。然后,渲染表单的React组件也进行控制 该表单在后续用户输入时发生了什么。输入表单 元素的值是由React以这种方式控制的,称为 “控制组件”。< / p >

如果使用受控组件,则必须在值的每次更改时更新状态。为此,需要将事件处理程序绑定到组件。在文档的示例中,通常是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函数将总是被触发,以更新并保持正确的状态。状态将始终具有更新后的值,并且当表单提交时,该值将从状态中获取。如果您的表单非常长,这可能是一个缺点,因为您必须为每个组件创建一个函数,或者编写一个简单的函数来处理每个组件的值更改。

不受控制的

文档-未受控组件

在大多数情况下,我们建议使用受控组件来实现 形式。在受控组件中,表单数据由React处理 组件。另一种方法是不受控制的组件,其中表单数据

写入一个未受控组件,而不是写入一个事件 对于每个状态更新,都可以使用ref来获取表单值

这里的主要区别是,您不使用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>

如果使用不受控制的组件,则不需要绑定handleChange函数。提交表单时,将从DOM中获取值,此时可以进行必要的验证。也不需要为任何输入组件创建任何处理程序函数。

你的问题

现在,关于你的问题:

... 我想让它在我按回车键时被调用,当整个数字已经输入

如果您希望实现这一点,请使用不受控制的组件。如果没有必要,不要创建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键时,我们将用户的输入传递给父组件。

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>
)
}
}

我更喜欢onKeyUp,因为它只在释放键时触发。另一方面,如果用户出于某种原因按下并按住键,onKeyDown将触发多次。例如,当听“pressing”;Enter键来发出网络请求,你不希望多次触发它,因为它可能会很昂贵。

// handler could be passed as a prop
<input type="text" onKeyUp={handleKeyPress} />


handleKeyPress(e) {
if (e.key === 'Enter') {
// do whatever
}

另外,不要使用keyCode,因为它有时会被弃用。

防止输入提交表单的例子,在我的情况下,它是一个谷歌地图位置自动完成输入

<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()
}
}}
/>
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");
}
});