per chiamare l'evento onChange dopo aver premuto il tasto Invio


204

Sono nuovo di Bootstrap e bloccato con questo problema. Ho un campo di input e non appena inserisco solo una cifra, onChangeviene chiamata la funzione da , ma voglio che venga chiamata quando premo 'Invio quando è stato inserito l'intero numero. Lo stesso problema per la funzione di validazione: chiama troppo presto.

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

Risposte:


404

Secondo React Doc , potresti ascoltare gli eventi della tastiera, come onKeyPresso onKeyUpno 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');
    }
  }
});

Aggiornamento: utilizzare React.Component

Ecco il codice che utilizza React.Component che fa la stessa cosa

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

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

Ecco il jsfiddle .

Aggiornamento 2: utilizzare un componente funzionale

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

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

2
E desideri anche associare il processo di convalida onBlurall'evento.
Wuct

5
Stessa soluzione in modo più compatto con riferimento al testo inserito:<input ref='reference' onKeyPress={(e) => {(e.key === 'Enter' ? doSomething(this.refs.reference.value) : null)}} />
musemind

5
@musemind In realtà, non è necessario utilizzare ref. <input onKeyPress={e => doSomething(e.target.value)}è sufficiente.
Salta il

4
@musemind Il punto di usare un metodo di classe invece di una funzione inline è di evitare di creare una nuova funzione ogni volta che onKeyPressviene attivato. È un sottile miglioramento del perf.
Wuct

1
il violino in allegato non funziona più, si prega di controllare, comunque bella risposta
Pardeep Jain

52

È possibile utilizzare onKeyPress direttamente nel campo di input. La funzione onChange cambia il valore dello stato ad ogni cambio del campo di input e dopo aver premuto Invio, chiamerà una funzione di ricerca ().

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

questa risposta funziona per me piuttosto che per la risposta accettata sopra.
karthik Shankar,

Se hai una forma pesante, consiglierei di creare una funzione al di fuori del metodo di rendering e passarla come riferimento, come onKeyPress={this.yourFunc}altrimenti la funzione di freccia grassa verrà ricreata su ogni rendering.
Viktor,

questo funziona nel caso in cui l'evento onKeyPress sia scritto anche per l'input e il caso genitore. Grazie.
Naveen Kumar PG

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

24

premendo Invio quando lo stato submitattivo su un controllo modulo (input) in genere attiva un evento (onSubmit) sul modulo stesso (non l'input) in modo da poter associare this.handleInputil modulo a onSubmit.

In alternativa, è possibile associarlo blurall'evento (onBlur) sul inputquale si verifica quando viene rimosso lo stato attivo (ad esempio, la tabulazione all'elemento successivo che può ottenere lo stato attivo)


3
Questo è molto più pulito dell'uso onKeyPress.
Blackus,

1
Pensato poiché l'obiettivo è diverso, event.target.valuenon è disponibile
Izkata

@Izkata quello che dici è assolutamente corretto; la mia risposta potrebbe richiedere un modo diverso di gestire le cose nel handleInputmetodo del controller . Fare secondo la mia risposta ti coprirebbe sia quando l'utente preme invio mentre si concentra sull'input sia quando si attiva un submitpulsante / input.
Luca,

Nella maggior parte delle situazioni nelle app Web non ci sono moduli, ma solo input, quindi questa risposta non è rilevante per la maggior parte dei casi d'uso, IMHO
vsync

@vsync potrebbe non essere rilevante per la maggioranza, ma comunque valido per una parte - e sicuramente non errato, non penso che valga la pena di votare?
Luca,

8

Puoi usare 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

Reagisci agli utenti, ecco una risposta per completezza.

Reagire versione 16.4.2

O vuoi aggiornare per ogni sequenza di tasti, o ottenere il valore solo al momento dell'invio. L'aggiunta degli eventi chiave al componente funziona, ma ci sono alternative come raccomandato nei documenti ufficiali.

Componenti controllati e non controllati

Controlled

Da Documenti - Moduli e componenti controllati :

In HTML, elementi del modulo come input, textarea e select in genere mantengono il proprio stato e lo aggiornano in base all'input dell'utente. In React, lo stato mutabile viene in genere mantenuto nella proprietà state dei componenti e aggiornato solo con setState ().

Possiamo combinare i due facendo diventare lo stato Reattivo la "singola fonte di verità". Quindi il componente React che esegue il rendering di un modulo controlla anche cosa succede in quel modulo al successivo input dell'utente. Un elemento del modulo di input il cui valore è controllato da React in questo modo è chiamato "componente controllato".

Se si utilizza un componente controllato, è necessario mantenere lo stato aggiornato per ogni modifica al valore. Perché ciò accada, si associa un gestore eventi al componente. Negli esempi dei documenti, di solito l'evento onChange.

Esempio:

1) Gestore dell'evento associato nel costruttore (valore mantenuto nello stato)

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

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

2) Crea funzione gestore

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

3) Crea la funzione di invio del modulo (il valore è preso dallo stato)

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

4) Rendering

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

Se si utilizzano componenti controllati , la handleChangefunzione verrà sempre attivata, al fine di aggiornare e mantenere lo stato corretto. Lo stato avrà sempre il valore aggiornato e quando il modulo viene inviato, il valore verrà preso dallo stato. Questo potrebbe essere un contro se il tuo modulo è molto lungo, perché dovrai creare una funzione per ogni componente o scriverne una semplice che gestisca il cambio di valore di ogni componente.

sfrenato

Da Documenti - Componente non controllato

Nella maggior parte dei casi, si consiglia di utilizzare componenti controllati per implementare i moduli. In un componente controllato, i dati del modulo sono gestiti da un componente React. L'alternativa sono i componenti non controllati, in cui i dati dei moduli sono gestiti dal DOM stesso.

Per scrivere un componente non controllato, invece di scrivere un gestore eventi per ogni aggiornamento di stato, è possibile utilizzare un riferimento per ottenere i valori del modulo dal DOM.

La differenza principale qui è che non si utilizza la onChangefunzione, ma piuttosto onSubmitil modulo per ottenere i valori e convalidare se necessario.

Esempio:

1) Associa il gestore eventi e crea riferimento all'input nel costruttore (nessun valore mantenuto nello stato)

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

2) Crea la funzione di invio del modulo (il valore è preso dal componente DOM)

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

3) Rendering

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

Se si utilizzano componenti non controllati , non è necessario associare una handleChangefunzione. Quando il modulo viene inviato, il valore verrà preso dal DOM e le convalide necessarie possono avvenire a questo punto. Non è necessario creare alcuna funzione del gestore per nessuno dei componenti di input.

Il tuo problema

Ora, per il tuo problema:

... Voglio che venga chiamato quando premo 'Invio quando è stato inserito l'intero numero

Se si desidera ottenere ciò, utilizzare un componente non controllato. Non creare i gestori onChange se non è necessario. La enterchiave invierà il modulo e la handleSubmitfunzione verrà attivata.

Modifiche che devi fare:

Rimuovi la chiamata onChange nel tuo elemento

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

Gestisci il modulo di invio e convalida i tuoi input. È necessario ottenere il valore dall'elemento nella funzione di invio del modulo e quindi convalidare. Assicurati di creare il riferimento al tuo elemento nel costruttore.

  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
  }

Esempio di utilizzo di un componente non controllato:

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

Puoi anche scrivere una piccola funzione wrapper come questa

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

Quindi consumalo sui tuoi input

<input 
    type="text" 
    placeholder="Title of todo" 
    onChange={e => setName(e.target.value)}
    onKeyPress={e => onEnter(e, addItem)}/>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.