để gọi sự kiện onChange sau khi nhấn phím Enter


204

Tôi mới sử dụng Bootstrap và bị mắc kẹt với vấn đề này. Tôi có một trường đầu vào và ngay khi tôi nhập chỉ một chữ số, hàm từ onChangeđược gọi, nhưng tôi muốn nó được gọi khi tôi nhấn 'Enter khi toàn bộ số đã được nhập. Vấn đề tương tự cho chức năng xác nhận - nó gọi quá sớm.

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

Câu trả lời:


404

Theo React Doc , bạn có thể nghe các sự kiện bàn phím, thích onKeyPresshay onKeyUpkhông 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');
    }
  }
});

Cập nhật: Sử dụng React.Component

Đây là đoạn mã sử dụng React.Component thực hiện điều tương tự

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

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

Đây là jsfiddle .

Cập nhật 2: Sử dụng một thành phần chức năng

const Input = () => {
  const handleKeyDown = (event) => {
    if (event.key === 'Enter') {
      console.log('do validate')
    }
  }

  return <input type="text" onKeyDown={handleKeyDown} />
}

2
Và bạn cũng muốn liên kết quá trình xác nhận với onBlursự kiện.
vào

5
Cùng một giải pháp theo cách gọn nhẹ hơn với tham chiếu đến văn bản đầu vào:<input ref='reference' onKeyPress={(e) => {(e.key === 'Enter' ? doSomething(this.refs.reference.value) : null)}} />
musemind

5
@musemind Thật ra, bạn không cần sử dụng ref. <input onKeyPress={e => doSomething(e.target.value)}là đủ.
tiến hành

4
@musemind Điểm để sử dụng một phương thức lớp thay vì một hàm nội tuyến là để tránh tạo ra một hàm mới mỗi khi onKeyPressđược kích hoạt. Đó là một cải tiến hoàn hảo tinh tế.
tiến hành

1
Fiddle

52

Bạn có thể sử dụng onKeyPress trực tiếp trên trường đầu vào. Hàm onChange thay đổi giá trị trạng thái trên mỗi thay đổi trường đầu vào và sau khi nhấn Enter, nó sẽ gọi hàm tìm kiếm ().

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

câu trả lời này làm việc cho tôi chứ không phải là câu trả lời được chấp nhận ở trên.
karthik shankar

Nếu bạn có dạng nặng, tôi khuyên bạn nên tạo chức năng bên ngoài phương thức kết xuất và chuyển nó làm tham chiếu, giống như onKeyPress={this.yourFunc}chức năng mũi tên béo sẽ được tạo lại trên mỗi kết xuất.
Viktor

điều này hoạt động cho trường hợp trong đó sự kiện onKeyPress được viết cho trường hợp đầu vào và trường hợp cha. cảm ơn.
Naveen Kumar PG

HoặconKeyPress={event => event.key === 'Enter' && this.search()}
camden_kid

24

nhấn Enter khi tiêu điểm trong điều khiển biểu mẫu (đầu vào) thường kích hoạt submitsự kiện (onSubmit) trên chính biểu mẫu (không phải đầu vào) để bạn có thể liên kếtthis.handleInput biểu mẫu trên biểu mẫu.

Ngoài ra, bạn có thể liên kết nó với blursự kiện (onBlur) inputxảy ra khi tiêu điểm bị xóa (ví dụ: gắn thẻ vào phần tử tiếp theo có thể lấy nét)


3
Điều này là sạch hơn nhiều so với sử dụng onKeyPress.
Blackus

1
Suy nghĩ vì mục tiêu là khác nhau, event.target.valuekhông có sẵn
Izkata

@Izkata những gì bạn nói là hoàn toàn chính xác; câu trả lời của tôi có thể yêu cầu một cách xử lý khác nhau trong handleInputphương thức điều khiển . Làm theo câu trả lời của tôi sẽ bao gồm cả bạn khi người dùng nhấn enter trong khi tập trung vào đầu vào và khi kích hoạt submitnút / đầu vào.
Luca

Trong hầu hết các tình huống trong ứng dụng web không có biểu mẫu, chỉ có đầu vào, vì vậy câu trả lời này không liên quan đến phần lớn các trường hợp sử dụng, IMHO
vsync

@vsync nó có thể không liên quan đến đa số, nhưng vẫn hợp lệ cho một phần - và chắc chắn không chính xác, tôi không nghĩ rằng nó đáng để downvote?
Luca

8

Bạn có thể dùng 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>


5

Phản ứng người dùng, đây là một câu trả lời cho sự đầy đủ.

Phản ứng phiên bản 16.4.2

Bạn có thể muốn cập nhật cho mọi tổ hợp phím hoặc chỉ nhận giá trị khi gửi. Thêm các sự kiện quan trọng vào thành phần hoạt động, nhưng có những lựa chọn thay thế như được khuyến nghị trong các tài liệu chính thức.

Các thành phần được kiểm soát và không được kiểm soát

Kiểm soát

Từ Tài liệu - Biểu mẫu và thành phần được kiểm soát :

Trong HTML, các thành phần biểu mẫu như đầu vào, textarea và chọn thường duy trì trạng thái của riêng chúng và cập nhật nó dựa trên đầu vào của người dùng. Trong React, trạng thái có thể thay đổi thường được giữ trong thuộc tính trạng thái của các thành phần và chỉ được cập nhật với setState ().

Chúng ta có thể kết hợp cả hai bằng cách làm cho trạng thái React trở thành nguồn duy nhất của sự thật. Sau đó, thành phần React biểu hiện một biểu mẫu cũng kiểm soát những gì xảy ra trong biểu mẫu đó trên đầu vào của người dùng tiếp theo. Một phần tử biểu mẫu đầu vào có giá trị được điều khiển bởi React theo cách này được gọi là thành phần được điều khiển bởi thành viên.

Nếu bạn sử dụng một thành phần được kiểm soát, bạn sẽ phải cập nhật trạng thái cho mỗi thay đổi đối với giá trị. Để điều này xảy ra, bạn liên kết một trình xử lý sự kiện với thành phần. Trong các ví dụ của tài liệu, thường là sự kiện onChange.

Thí dụ:

1) Trình xử lý sự kiện ràng buộc trong hàm tạo (giá trị được giữ ở trạng thái)

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

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

2) Tạo chức năng xử lý

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

3) Tạo chức năng gửi biểu mẫu (giá trị được lấy từ trạng thái)

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

4) Kết xuất

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

Nếu bạn sử dụng các thành phần được kiểm soát ,handleChange chức năng sẽ luôn được kích hoạt, để cập nhật và giữ trạng thái thích hợp. Trạng thái sẽ luôn có giá trị cập nhật và khi biểu mẫu được gửi, giá trị sẽ được lấy từ trạng thái. Đây có thể là một con lừa nếu hình thức của bạn rất dài, bởi vì bạn sẽ phải tạo một hàm cho mọi thành phần hoặc viết một hàm đơn giản xử lý mọi thay đổi giá trị của mọi thành phần.

Không được kiểm soát

Từ Docs - Thành phần không được kiểm soát

Trong hầu hết các trường hợp, chúng tôi khuyên bạn nên sử dụng các thành phần được kiểm soát để triển khai các biểu mẫu. Trong thành phần được kiểm soát, dữ liệu biểu mẫu được xử lý bởi thành phần React. Sự thay thế là các thành phần không được kiểm soát, trong đó dữ liệu biểu mẫu được xử lý bởi chính DOM.

Để viết một thành phần không được kiểm soát, thay vì viết một trình xử lý sự kiện cho mỗi bản cập nhật trạng thái, bạn có thể sử dụng một tham chiếu để nhận các giá trị biểu mẫu từ DOM.

Sự khác biệt chính ở đây là bạn không sử dụng onChangehàm, mà thay vào đó onSubmitlà biểu mẫu để nhận các giá trị và xác thực nếu cần thiết.

Thí dụ:

1) Xử lý ràng buộc sự kiện và tạo ref cho đầu vào trong hàm tạo (không có giá trị nào được giữ ở trạng thái)

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

2) Tạo chức năng gửi biểu mẫu (giá trị được lấy từ thành phần DOM)

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

3) Kết xuất

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

Nếu bạn sử dụng các thành phần không được kiểm soát , không cần phải liên kết một handleChangechức năng. Khi biểu mẫu được gửi, giá trị sẽ được lấy từ DOM và các xác nhận cần thiết có thể xảy ra tại thời điểm này. Không cần phải tạo bất kỳ chức năng xử lý nào cho bất kỳ thành phần đầu vào nào.

Vấn đề của bạn

Bây giờ, cho vấn đề của bạn:

... Tôi muốn nó được gọi khi tôi nhấn 'Enter khi toàn bộ số đã được nhập

Nếu bạn muốn đạt được điều này, hãy sử dụng một thành phần không được kiểm soát. Đừng tạo trình xử lý onChange nếu không cần thiết. Các enterchính sẽ gửi biểu mẫu và các handleSubmitchức năng sẽ bị sa thải.

Những thay đổi bạn cần làm:

Xóa cuộc gọi onChange trong phần tử của bạn

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

Xử lý các hình thức gửi và xác nhận đầu vào của bạn. Bạn cần lấy giá trị từ phần tử của mình trong hàm gửi biểu mẫu và sau đó xác thực. Hãy chắc chắn rằng bạn tạo tham chiếu đến phần tử của bạn trong hàm tạo.

  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
  }

Ví dụ sử dụng một thành phần không được kiểm soát:

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')
);

3

Bạn cũng có thể viết một hàm bao bọc nhỏ như thế này

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

Sau đó tiêu thụ nó vào đầu vào của bạn

<input 
    type="text" 
    placeholder="Title of todo" 
    onChange={e => setName(e.target.value)}
    onKeyPress={e => onEnter(e, addItem)}/>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.