wywołać zdarzenie Zmień po naciśnięciu klawisza Enter


204

Jestem nowy w Bootstrap i utknąłem z tym problemem. Mam pole wprowadzania i jak tylko wprowadzę tylko jedną cyfrę, onChangewywoływana jest funkcja from , ale chcę, aby została wywołana po naciśnięciu klawisza „Enter” po wprowadzeniu liczby całkowitej. Ten sam problem z funkcją sprawdzania poprawności - wywołuje zbyt wcześnie.

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

Odpowiedzi:


404

Według React Doc można słuchać zdarzeń na klawiaturze, takich jak onKeyPresslub onKeyUpnie 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');
    }
  }
});

Aktualizacja: użyj React.Component

Oto kod używający React.Component, który robi to samo

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

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

Oto jsfiddle .

Aktualizacja 2: Użyj komponentu funkcjonalnego

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

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

2
Chciałbyś również powiązać proces sprawdzania poprawności ze onBlurzdarzeniem.
wuct

5
To samo rozwiązanie w bardziej zwięzły sposób w odniesieniu do tekstu wejściowego:<input ref='reference' onKeyPress={(e) => {(e.key === 'Enter' ? doSomething(this.refs.reference.value) : null)}} />
musemind 30.07.16

5
@musemind W rzeczywistości nie musisz używać ref. <input onKeyPress={e => doSomething(e.target.value)}jest wystarczający.
wuct

4
@musemind Celem użycia metody klasowej zamiast funkcji wbudowanej jest uniknięcie tworzenia nowej funkcji za każdym razem, gdy onKeyPressjest uruchamiana. Jest to subtelna poprawa wydajności.
wuct

1
dołączone skrzypce już nie działa, proszę sprawdzić, w każdym razie ładna odpowiedź
Pardeep Jain

52

Możesz użyć onKeyPress bezpośrednio w polu wprowadzania. Funkcja onChange zmienia wartość stanu przy każdej zmianie pola wprowadzania, a po naciśnięciu Enter wywoła funkcję wyszukiwania ().

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

ta odpowiedź działa raczej dla mnie niż na zaakceptowaną odpowiedź powyżej.
karthik shankar

Jeśli masz ciężką postać, poleciłbym utworzyć funkcję poza metodą renderowania i przekazać ją jako odniesienie, w onKeyPress={this.yourFunc}przeciwnym razie funkcja renderowania grubych strzałek zostanie utworzona na każdym renderowaniu.
Viktor,

działa to w przypadku, gdy zdarzenie onKeyPress jest zapisywane również dla przypadku wejściowego i przypadku nadrzędnego. dzięki.
Naveen Kumar PG

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

24

naciśnięcie klawisza Enter, gdy fokus na kontroli formularza (dane wejściowe) normalnie wyzwala submitzdarzenie (onSubmit) w samym formularzu (nie w danych wejściowych), aby można było powiązać this.handleInputgo z formularzem onSubmit.

Alternatywnie możesz powiązać to ze blurzdarzeniem (onBlur), inputktóre dzieje się po usunięciu fokusa (np. Tabulacja do następnego elementu, który może uzyskać fokus)


3
Jest to o wiele bardziej czysty niż używanie onKeyPress.
Blackus

1
Myśl, ponieważ cel jest inny, event.target.valuenie jest dostępna
Izkata

@ Izkata to, co mówisz, jest całkowicie poprawne; moja odpowiedź może wymagać innego sposobu obsługi rzeczy w handleInputmetodzie kontrolera . Postępowanie zgodnie z moją odpowiedzią obejmowałoby was zarówno, gdy użytkownik naciska klawisz enter, skupiając się na wejściu, a także podczas aktywacji submitprzycisku / wejścia.
Luca,

W większości sytuacji w aplikacjach internetowych nie ma formularzy, tylko dane wejściowe, więc ta odpowiedź nie dotyczy większości przypadków użycia, IMHO
vsync

@vsync może nie być odpowiedni dla większości, ale nadal ważny dla części - i zdecydowanie nie jest niepoprawny, nie sądzę, że warto go głosować?
Luca

8

Możesz użyć 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

Reakcja użytkowników, oto odpowiedź na kompletność.

Wersja React 16.4.2

Albo chcesz aktualizować za każdym naciśnięciem klawisza, albo uzyskaj wartość tylko przy wysyłaniu. Dodanie kluczowych zdarzeń do komponentu działa, ale istnieją alternatywne rozwiązania zalecane w oficjalnych dokumentach.

Kontrolowane a niekontrolowane komponenty

Kontrolowane

Z Dokumentów - formularze i kontrolowane komponenty :

W HTML formuj elementy, takie jak input, textarea i select, zwykle zachowują własny stan i aktualizują go na podstawie danych wprowadzonych przez użytkownika. W React stan mutable jest zwykle utrzymywany we właściwości state składników i aktualizowany tylko za pomocą setState ().

Możemy połączyć te dwa elementy, czyniąc stan React „jedynym źródłem prawdy”. Następnie komponent React, który renderuje formularz, kontroluje również to, co dzieje się w tej formie podczas wprowadzania danych przez użytkownika. Element formularza wejściowego, którego wartość jest kontrolowana w ten sposób przez React, nazywany jest „komponentem kontrolowanym”.

Jeśli używasz kontrolowanego komponentu, będziesz musiał aktualizować stan dla każdej zmiany wartości. Aby tak się stało, należy powiązać moduł obsługi zdarzeń ze składnikiem. W przykładach dokumentów zwykle zdarzenie onChange.

Przykład:

1) Obsługa zdarzenia powiązania w konstruktorze (wartość zachowana w stanie)

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

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

2) Utwórz funkcję modułu obsługi

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

3) Utwórz funkcję przesyłania formularza (wartość pochodzi ze stanu)

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

4) Renderuj

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

Jeśli używasz kontrolowanych komponentów, twoja handleChangefunkcja będzie zawsze uruchamiana w celu aktualizacji i utrzymania właściwego stanu. Stan zawsze będzie miał zaktualizowaną wartość, a po przesłaniu formularza wartość zostanie pobrana ze stanu. Może to być oszustwem, jeśli twoja forma jest bardzo długa, ponieważ będziesz musiał utworzyć funkcję dla każdego komponentu lub napisać prostą, która będzie obsługiwać zmianę wartości każdego komponentu.

Niekontrolowane

Z Dokumentów - niekontrolowany komponent

W większości przypadków zalecamy stosowanie kontrolowanych komponentów do implementacji formularzy. W kontrolowanym komponencie dane formularza są obsługiwane przez komponent React. Alternatywą są niekontrolowane komponenty, w których dane formularza są obsługiwane przez sam DOM.

Aby napisać niekontrolowany komponent, zamiast pisać moduł obsługi zdarzeń dla każdej aktualizacji stanu, możesz użyć polecenia ref, aby uzyskać wartości formularza z DOM.

Główną różnicą tutaj jest to, że nie używasz onChangefunkcji, ale onSubmitformę, aby uzyskać wartości i zweryfikować, jeśli to konieczne.

Przykład:

1) Powiązanie modułu obsługi zdarzeń i utworzenie referencji w celu wprowadzenia do konstruktora (brak wartości w stanie)

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

2) Utwórz funkcję przesyłania formularza (wartość pochodzi z komponentu DOM)

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

3) Renderuj

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

Jeśli używasz niekontrolowanych komponentów, nie ma potrzeby wiązania handleChangefunkcji. Po przesłaniu formularza wartość zostanie pobrana z modelu DOM i w tym momencie mogą wystąpić niezbędne weryfikacje. Nie trzeba też tworzyć żadnych funkcji obsługi dla żadnego z komponentów wejściowych.

Twój problem

Teraz dla twojego problemu:

... Chcę, aby został wywołany po naciśnięciu klawisza Enter po wprowadzeniu całego numeru

Jeśli chcesz to osiągnąć, użyj niekontrolowanego komponentu. Nie twórz programów obsługi onChange, jeśli nie jest to konieczne. enterKlucz będzie przesłać formularz, a handleSubmitfunkcja zostanie zwolniony.

Zmiany, które musisz wykonać:

Usuń wywołanie onChange w swoim elemencie

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

Obsługuj formularz prześlij i sprawdź poprawność wprowadzonych danych. Musisz pobrać wartość ze swojego elementu w funkcji przesyłania formularza, a następnie sprawdzić poprawność. Upewnij się, że utworzyłeś odniesienie do swojego elementu w konstruktorze.

  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
  }

Przykładowe zastosowanie niekontrolowanego komponentu:

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

Możesz także napisać taką funkcję otoki

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

Następnie zużyj go na swoich danych wejściowych

<input 
    type="text" 
    placeholder="Title of todo" 
    onChange={e => setName(e.target.value)}
    onKeyPress={e => onEnter(e, addItem)}/>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.