para llamar al evento onChange después de presionar la tecla Enter

204

Soy nuevo en Bootstrap y me quedé con este problema. Tengo un campo de entrada y tan pronto como ingreso solo un dígito, onChangese llama a la función from , pero quiero que se llame cuando presiono 'Enter cuando se ha ingresado el número completo. El mismo problema para la función de validación: llama demasiado pronto.

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
});
Bill Lumbert
fuente

Respuestas:

404

Según React Doc , puedes escuchar eventos de teclado, como 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');
    }
  }
});

Actualización: Use React.Component

Aquí está el código usando React.Component que hace lo mismo

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

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

Aquí está el jsfiddle .

Actualización 2: use un componente funcional

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

  return <input type="text" onKeyDown={handleKeyDown} />
}
wuct
fuente
2
Y también le gustaría vincular el proceso de validación al onBlurevento.
wuct
55
La misma solución de una manera más compacta con referencia al texto de entrada:<input ref='reference' onKeyPress={(e) => {(e.key === 'Enter' ? doSomething(this.refs.reference.value) : null)}} />
musemind
55
@musemind En realidad, no necesitas usar ref. <input onKeyPress={e => doSomething(e.target.value)}es suficiente.
wuct
44
@musemind El objetivo de utilizar un método de clase en lugar de una función en línea es evitar crear una nueva función cada vez que onKeyPressse activa. Es una mejora sutil de rendimiento.
wuct
1
el violín adjunto ya no funciona, compruebe, de todos modos, una buena respuesta
Pardeep Jain
52

Puede usar onKeyPress directamente en el campo de entrada. La función onChange cambia el valor de estado en cada cambio de campo de entrada y después de presionar Enter se llamará a una función de búsqueda ().

<input
    type="text"
    placeholder="Search..."
    onChange={event => {this.setState({query: event.target.value})}}
    onKeyPress={event => {
                if (event.key === 'Enter') {
                  this.search()
                }
              }}
/>
Admir
fuente
esta respuesta funciona para mí en lugar de la respuesta aceptada arriba.
karthik shankar
Si tiene una forma pesada, recomendaría crear una función fuera del método de representación y pasarla como referencia, de lo onKeyPress={this.yourFunc}contrario, la función de flecha gruesa se volverá a crear en cada representación.
Viktor
esto está funcionando para el caso en el que el evento onKeyPress se escribe para la entrada y el caso primario también. Gracias.
Naveen Kumar PG
O bienonKeyPress={event => event.key === 'Enter' && this.search()}
camden_kid
24

Al presionar Intro cuando el foco en un control de formulario (entrada) normalmente activa un submitevento (onSubmit) en el formulario en sí (no en la entrada) para que pueda vincular suthis.handleInput al formulario onSubmit.

Alternativamente, puede vincularlo al blurevento (onBlur) en el inputque sucede cuando se elimina el foco (por ejemplo, tabular al siguiente elemento que puede enfocarse)

Luca
fuente
3
Esto es mucho más limpio que usar onKeyPress.
Blackus
1
Pensado ya que el objetivo es diferente, event.target.valueno está disponible
Izkata
@Izkata lo que dices es absolutamente correcto; mi respuesta podría requerir una forma diferente de manejar las cosas en el handleInputmétodo del controlador . Hacer según mi respuesta los cubriría a ambos cuando el usuario presiona enter mientras se enfoca en la entrada y cuando activa un submitbotón / entrada.
Luca
En la mayoría de las situaciones en las aplicaciones web no hay formularios, solo entradas, por lo que esta respuesta no es relevante para la mayoría de los casos de uso, en mi humilde opinión
vsync
@vsync podría no ser relevante para la mayoría, pero aún válido para una parte, y definitivamente no es incorrecto, ¿no creo que valga la pena un voto negativo?
Luca
8

Puedes usar 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>

onmyway133
fuente
5

Reaccionar usuarios, aquí hay una respuesta para completar.

Reaccionar versión 16.4.2

Desea actualizar para cada pulsación de tecla u obtener el valor solo al enviar. Agregar los eventos clave al componente funciona, pero hay alternativas como se recomienda en los documentos oficiales.

Componentes controlados vs no controlados

Revisado

De los Documentos - Formularios y componentes controlados :

En HTML, los elementos de formulario como input, textarea y select normalmente mantienen su propio estado y lo actualizan según la entrada del usuario. En React, el estado mutable generalmente se mantiene en la propiedad de estado de los componentes y solo se actualiza con setState ().

Podemos combinar los dos haciendo que el estado React sea la "fuente única de verdad". Luego, el componente React que representa un formulario también controla lo que sucede en ese formulario en la entrada posterior del usuario. Un elemento de formulario de entrada cuyo valor es controlado por React de esta manera se denomina "componente controlado".

Si utiliza un componente controlado, deberá mantener actualizado el estado para cada cambio en el valor. Para que esto suceda, debe vincular un controlador de eventos al componente. En los ejemplos de los documentos, generalmente el evento onChange.

Ejemplo:

1) Enlazar controlador de eventos en el constructor (valor mantenido en estado)

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

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

2) Crear función de controlador

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

3) Crear función de envío de formulario (el valor se toma del estado)

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

4) Renderizar

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

Si usa componentes controlados , suhandleChange función siempre se activará para actualizar y mantener el estado correcto. El estado siempre tendrá el valor actualizado, y cuando se envíe el formulario, el valor se tomará del estado. Esto podría ser una estafa si su formulario es muy largo, porque tendrá que crear una función para cada componente, o escribir una simple que maneje el cambio de valor de cada componente.

Sin control

De los documentos: componente no controlado

En la mayoría de los casos, recomendamos utilizar componentes controlados para implementar formularios. En un componente controlado, los datos del formulario son manejados por un componente React. La alternativa son los componentes no controlados, donde los datos del formulario son manejados por el propio DOM.

Para escribir un componente no controlado, en lugar de escribir un controlador de eventos para cada actualización de estado, puede usar una referencia para obtener valores de formulario del DOM.

La principal diferencia aquí es que no utiliza la onChangefunción, sino más bienonSubmit el formulario para obtener los valores y validar si es necesario.

Ejemplo:

1) Enlazar controlador de eventos y crear referencia a entrada en constructor (no se mantiene ningún valor en estado)

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

2) Crear función de envío de formulario (el valor se toma del componente DOM)

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

3) Renderizar

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

Si utiliza componentes no controlados , no es necesario vincular una handleChangefunción. Cuando se envía el formulario, el valor se tomará del DOM y las validaciones necesarias pueden ocurrir en este punto. No es necesario crear funciones de controlador para ninguno de los componentes de entrada también.

Tu problema

Ahora, para su problema:

... quiero que se llame cuando presiono 'Enter cuando se ha ingresado el número completo

Si desea lograr esto, use un componente no controlado. No cree los controladores onChange si no es necesario. La enterclave enviará el formulario y se handleSubmitactivará la función.

Cambios que debes hacer:

Elimine la llamada onChange en su 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
});

Maneje el envío del formulario y valide su entrada. Debe obtener el valor de su elemento en la función de envío del formulario y luego validarlo. Asegúrese de crear la referencia a su elemento en el constructor.

  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
  }

Ejemplo de uso de un componente no controlado:

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')
);
c-chavez
fuente
3

También puedes escribir una pequeña función de envoltura como esta

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

Luego consúmelo en tus entradas

<input 
    type="text" 
    placeholder="Title of todo" 
    onChange={e => setName(e.target.value)}
    onKeyPress={e => onEnter(e, addItem)}/>
David Alsh
fuente