我是新的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
});

在表单控件(input)中按Enter通常会触发表单上的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 event on Enter)在以下情况下执行:

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

这里有更多。

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


根据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。组件

下面是使用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版

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

受控组件与不受控组件

控制

从文档-表单和受控组件:

In HTML, form elements such as input, textarea, and select typically maintain their own state and update it based on user input. In React, mutable state is typically kept in the state property of components, and only updated with setState(). We can combine the two by making the React state be the “single source of truth”. Then the React component that renders a form also controls what happens in that form on subsequent user input. An input form element whose value is controlled by React in this way is called a “controlled component”.

如果使用受控组件,则必须在值的每次更改时更新状态。为此,需要将事件处理程序绑定到组件。在文档的示例中,通常是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 -受控组件

在大多数情况下,我们建议使用受控组件来实现 形式。在受控组件中,表单数据由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>

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

你的问题

现在,关于你的问题:

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

如果您希望实现这一点,请使用不受控制的组件。如果没有必要,不要创建onChange处理程序。输入键将提交表单,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将触发多次。例如,当监听“按下”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");
            }
        });