untuk memanggil onChange event setelah menekan tombol Enter


204

Saya baru mengenal Bootstrap dan terjebak dengan masalah ini. Saya memiliki bidang input dan segera setelah saya memasukkan hanya satu digit, fungsi dari onChangedipanggil, tetapi saya ingin itu dipanggil ketika saya menekan 'Enter ketika seluruh nomor telah dimasukkan. Masalah yang sama untuk fungsi validasi - panggilannya terlalu cepat.

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

Jawaban:


404

Menurut React Doc , Anda dapat mendengarkan acara keyboard, suka onKeyPressatau onKeyUptidak 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');
    }
  }
});

Pembaruan: Gunakan React.Component

Berikut adalah kode menggunakan React.Component yang melakukan hal yang sama

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

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

Ini jsfiddle .

Pembaruan 2: Gunakan komponen fungsional

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

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

2
Dan Anda juga ingin mengikat proses validasi ke onBluracara.
laksanakan

5
Solusi yang sama dengan cara yang lebih ringkas dengan merujuk pada teks input:<input ref='reference' onKeyPress={(e) => {(e.key === 'Enter' ? doSomething(this.refs.reference.value) : null)}} />
musemind

5
@mememind Sebenarnya, Anda tidak perlu menggunakan ref. <input onKeyPress={e => doSomething(e.target.value)}Cukup.
laksanakan

4
@mememind Poin untuk menggunakan metode kelas alih-alih fungsi inline adalah untuk menghindari membuat fungsi baru setiap kali onKeyPressdipicu. Ini adalah peningkatan perf halus.
laksanakan

1
biola terlampir tidak berfungsi lagi, silakan periksa, lagian jawaban yang bagus
Pardeep Jain

52

Anda dapat menggunakan onKeyPress langsung pada bidang input. fungsi onChange mengubah nilai status pada setiap perubahan bidang input dan setelah Enter ditekan itu akan memanggil pencarian fungsi ().

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

jawaban ini lebih cocok untuk saya daripada jawaban yang diterima di atas.
karthik shankar

Jika Anda memiliki bentuk yang berat saya akan merekomendasikan untuk membuat fungsi di luar metode render dan meneruskannya sebagai referensi, seperti onKeyPress={this.yourFunc}jika fungsi panah gemuk akan dibuat kembali pada setiap render.
Viktor

ini berfungsi untuk case di mana event onKeyPress ditulis untuk input dan case induk juga. Terima kasih.
Naveen Kumar PG

AtauonKeyPress={event => event.key === 'Enter' && this.search()}
camden_kid

24

menekan Enter ketika fokus masuk pada kontrol formulir (input) biasanya memicu acara submit(onSubmit) pada formulir itu sendiri (bukan input) sehingga Anda bisa mengikat Anda this.handleInputke formulir onSubmit.

Atau Anda dapat mengikatnya ke acara blur(onBlur) inputyang terjadi ketika fokus dihapus (misalnya menabrak elemen berikutnya yang bisa mendapatkan fokus)


3
Ini jauh lebih bersih daripada menggunakan onKeyPress.
Blackus

1
Diperkirakan karena targetnya berbeda, event.target.valuetidak tersedia
Izkata

@Izkata apa yang Anda katakan benar-benar benar; jawaban saya mungkin memerlukan cara berbeda dalam menangani hal-hal dalam handleInputmetode pengontrol . Melakukan sesuai jawaban saya akan mencakup Anda berdua ketika pengguna menekan masuk sambil fokus pada input dan saat mengaktifkan submittombol / input.
Luca

Dalam sebagian besar situasi di aplikasi web tidak ada formulir, hanya input, jadi jawaban ini tidak relevan dengan sebagian besar kasus penggunaan, IMHO
vsync

@ vsync itu mungkin tidak relevan dengan mayoritas, tetapi masih berlaku untuk sebagian - dan jelas tidak salah, saya tidak berpikir itu layak downvote?
Luca

8

Kamu bisa memakai 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

Bereaksi pengguna, inilah jawaban untuk kelengkapannya.

Bereaksi versi 16.4.2

Anda ingin memperbarui untuk setiap penekanan tombol, atau mendapatkan nilainya hanya saat mengirim. Menambahkan acara utama ke komponen berfungsi, tetapi ada alternatif seperti yang direkomendasikan dalam dokumen resmi.

Komponen yang dikendalikan vs yang tidak terkontrol

Terkendali

Dari Documents - Formulir dan Komponen yang dikendalikan :

Dalam HTML, bentuk elemen seperti input, textarea, dan pilih biasanya mempertahankan negara mereka sendiri dan memperbaruinya berdasarkan input pengguna. Dalam Bereaksi, keadaan yang dapat berubah biasanya disimpan di properti komponen, dan hanya diperbarui dengan setState ().

Kita dapat menggabungkan keduanya dengan menjadikan negara Bereaksi menjadi "sumber kebenaran tunggal". Kemudian komponen Bereaksi yang membuat formulir juga mengontrol apa yang terjadi di formulir itu pada input pengguna berikutnya. Elemen formulir input yang nilainya dikendalikan oleh Bereaksi dengan cara ini disebut "komponen yang dikendalikan".

Jika Anda menggunakan komponen yang dikontrol Anda harus menjaga keadaan diperbarui untuk setiap perubahan nilai. Agar ini terjadi, Anda mengikat pengendali acara ke komponen. Dalam contoh-contoh dokumen, biasanya acara onChange.

Contoh:

1) Bind event handler dalam konstruktor (nilai disimpan dalam keadaan)

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

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

2) Buat fungsi handler

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

3) Buat fungsi kirim formulir (nilai diambil dari negara)

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

4) Memberikan

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

Jika Anda menggunakan komponen yang dikendalikan , AndahandleChange fungsi akan selalu diaktifkan, untuk memperbarui dan mempertahankan kondisi yang tepat. Negara akan selalu memiliki nilai yang diperbarui, dan ketika formulir dikirimkan, nilai akan diambil dari negara. Ini mungkin menjadi penipu jika formulir Anda sangat panjang, karena Anda harus membuat fungsi untuk setiap komponen, atau menulis yang sederhana yang menangani perubahan nilai setiap komponen.

Tidak terkendali

Dari Documents - komponen yang tidak terkontrol

Dalam kebanyakan kasus, kami merekomendasikan penggunaan komponen yang terkontrol untuk mengimplementasikan formulir. Dalam komponen yang dikendalikan, formulir data ditangani oleh komponen Bereaksi. Alternatifnya adalah komponen yang tidak terkontrol, di mana formulir data ditangani oleh DOM itu sendiri.

Untuk menulis komponen yang tidak terkontrol, alih-alih menulis pengendali acara untuk setiap pembaruan keadaan, Anda bisa menggunakan referensi untuk mendapatkan nilai formulir dari DOM.

Perbedaan utama di sini adalah bahwa Anda tidak menggunakan onChangefungsi, tetapi lebih onSubmitpada formulir untuk mendapatkan nilai, dan memvalidasi jika perlu.

Contoh:

1) Bind event handler dan buat ref to input dalam konstruktor (tidak ada nilai yang disimpan dalam keadaan)

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

2) Buat fungsi kirim formulir (nilai diambil dari komponen DOM)

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

3) Memberikan

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

Jika Anda menggunakan komponen yang tidak terkontrol , tidak perlu mengikat handleChangefungsi. Ketika formulir dikirimkan, nilainya akan diambil dari DOM dan validasi yang diperlukan dapat terjadi pada titik ini. Tidak perlu membuat fungsi handler untuk komponen input apa pun juga.

Masalah Anda

Sekarang, untuk masalah Anda:

... Saya ingin dipanggil ketika saya menekan 'Enter ketika seluruh nomor telah dimasukkan

Jika Anda ingin mencapai ini, gunakan komponen yang tidak terkontrol. Jangan membuat penangan onChange jika tidak perlu. The enterkey akan mengirimkan formulir dan handleSubmitfungsi akan dipecat.

Perubahan yang perlu Anda lakukan:

Hapus panggilan onChange di elemen Anda

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

Menangani formulir kirim dan validasi input Anda. Anda perlu mendapatkan nilai dari elemen Anda di fungsi kirim formulir lalu validasi. Pastikan Anda membuat referensi ke elemen Anda di konstruktor.

  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
  }

Contoh penggunaan komponen yang tidak terkontrol:

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

Anda juga dapat menulis fungsi pembungkus kecil seperti ini

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

Kemudian konsumsilah pada input Anda

<input 
    type="text" 
    placeholder="Title of todo" 
    onChange={e => setName(e.target.value)}
    onKeyPress={e => onEnter(e, addItem)}/>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.