No se puede escribir en el campo de texto de entrada React


111

Estoy probando mi primer fragmento de React.js y me quedé perplejo desde el principio ... Tengo el código a continuación, que genera un formulario de búsqueda en <div id="search"></div>. Pero escribir en el cuadro de búsqueda no hace nada.

Presumiblemente, algo está faltando al pasar los accesorios y el estado hacia arriba y hacia abajo, y esto parece un problema común. Pero estoy perplejo, no puedo ver lo que falta.

var SearchFacet = React.createClass({
  handleChange: function() {
    this.props.onUserInput(
      this.refs.searchStringInput.value
    )
  },
  render: function() {
    return (
      <div>
        Search for:
        <input
          type="text"
          value={this.props.searchString}
          ref="searchStringInput"
          onchange={this.handleChange} />
      </div>
    );
  }
});

var SearchTool = React.createClass({
  render: function() {
    return (
      <form>
        <SearchFacet 
          searchString={this.props.searchString}
          onUserInput={this.props.onUserInput}
         />
        <button>Search</button>
      </form>
    );
  }
});

var Searcher = React.createClass({
  getInitialState: function() {
    return {
      searchString: ''
    }
  },

  handleUserInput: function(searchString) {
    this.setState({
      searchString: searchString
    })
  },

  render: function() {
    return (
      <div>
        <SearchTool 
          searchString={this.state.searchString}
          onUserInput={this.handleUserInput}
        />
      </div>
    );
  }
});

ReactDOM.render(
  <Searcher />,
  document.getElementById('searcher')
);

(Eventualmente tendré otros tipos de SearchFacet*pero solo estoy tratando de que este funcione).


Intente iniciar sesión thiscuando ingrese el campo de texto. Podría ser que thisya no sea el Searchercomponente.
FaureHu

Gracias FaureHu - ¿registrando thisen qué punto del código? Intenta iniciar sesión Searcher.handleUserInput()o SearchFacet.handleChange()no hace nada.
Phil Gyford

puedes ver mi respuesta para preguntas similares. Puede encontrar una explicación detallada: stackoverflow.com/questions/34713718/…
prudhvi seeramreddi

Respuestas:


80

No ha encajado correctamente su onchangeutilería en el input. Debe estar onChangeen JSX.

<input
  type="text"
  value={this.props.searchString}
  ref="searchStringInput"
  onchange={this.handleChange} <--[should be onChange]
/>  

El tema de pasar un valueaccesorio a un <input>, y luego de alguna manera cambiar el valor pasado en respuesta a la interacción del usuario usando un onChangecontrolador está bastante bien considerado en los documentos .

Se refieren a entradas como componentes controlados y se refieren a entradas que, en cambio, permiten que el DOM maneje de forma nativa el valor de la entrada y los cambios posteriores del usuario como componentes no controlados .

Siempre que establezca el valueprop de an inputen alguna variable, tendrá un componente controlado . Esto significa que debe cambiar el valor de la variable por algún medio programático o, de lo contrario, la entrada siempre mantendrá ese valor y nunca cambiará, incluso cuando escriba: el comportamiento nativo de la entrada, para actualizar su valor al escribir, se anula. por React here.

Entonces, está tomando correctamente esa variable del estado y tiene un controlador para actualizar el estado, todo configurado correctamente. El problema fue porque usted tiene onchangey no el correcto, onChangenunca se llamó al controlador y, por lo tanto, valuenunca se actualizó cuando ingresó la entrada. Cuando usa, se llama onChangeal controlador , se actualiza cuando escribe y ve sus cambios.value


201

El uso value={whatever}hará que no pueda escribir en el campo de entrada. Deberías usar defaultValue="Hello!".

Consulte https://facebook.github.io/react/docs/uncontrolled-components.html#default-values

Además, onchangedebería ser onChangecomo señala @davnicwil.


2
En mi requisito, quería ingresar el campo con la habilitación de escritura y también debe establecerse en el valor predeterminado que proviene de una variable de estado. El atributo defaultValue estaba bien, pero hay un problema al actualizar el valor predeterminado de acuerdo con los cambios de estado, ¿hay alguna forma de forzar el cambio del valor predeterminado?
semira

1
Debería publicar ese problema como otra pregunta en Stackoverflow.
Ivan

1
@GeoffreyHale No estoy muy seguro de a qué te refieres con lo engañoso que es. Vea este ejemplo que no usa el estado: codepen.io/anon/pen/BQJZwr?editors=0010 . O este que lo hace: codepen.io/anon/pen/JbMJMX?editors=0010
Ivan

4
@Ivan Tienes razón, ambos son inmutables: value={whatever}y value={this.state.myvalue}. Debería haber hecho esta aclaración en su lugar: usar onChange={this.handleChange}y cualquier cosa como handleChange: function(e) { var newState = {}; newState[e.target.name] = e.target.value; this.setState(newState); },hace que los campos sean mutables nuevamente.
Geoffrey Hale

1
@Ivan Este me acaba de ayudar. Muchas gracias a defaultValuesalvar mi día.
Code Cooker

11

Esto puede deberse a que la función onChange no actualiza el valor adecuado que se menciona en la entrada.

Ejemplo:

<input type="text" value={this.state.textValue} onChange = {this.changeText}></input>

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

en la función onChange actualice el campo de valor mencionado.


Gracias, muy útil. Solo su respuesta explica en su totalidad cómo resolver el problema.
M3RS

donde definir esta func changeText?
Jitendra Pancholi

Si es un componente sin estado, dentro de la función, y si es un componente de clase, dentro del constructor.
Gal Grünfeld

no es necesario escribir this.state dentro de setState. Si solo escribe textValue: event.target.value dentro de setState, también funciona perfectamente
Pardeep Sharma

4

También tengo el mismo problema y en mi caso inyecté el reductor correctamente pero aún así no pude escribir en el campo. Resulta que si estás usando immutabletienes que usar redux-form/immutable.

import {reducer as formReducer} from 'redux-form/immutable';
const reducer = combineReducers{

    form: formReducer
}
import {Field, reduxForm} from 'redux-form/immutable';
/* your component */

Tenga en cuenta que su estado debería ser como, de lo state->formcontrario, debe configurar explícitamente la biblioteca y el nombre del estado debería ser form. ver este problema


4

Para mí, el siguiente cambio simple funcionó perfectamente

<input type="text" 
        value={props.letter} 
        onChange={event => setTxtLetter(event.target.value)} /> {/* does not work */}

cambiar ... valor = {myPropVal} a ... defaultValue = {myPropVal}

<input type="text" 
        defaultValue={props.letter} 
        onChange={event => setTxtLetter(event.target.value)} /> {/* Works!! */}

Esto me lo arregló ¡Gracias!
mikeym

Creo que onChange no funciona correctamente cuando se usa dentro de Formik. También estaba intentando esto, pero no funcionó para mí. ¿Podrías echar un vistazo aquí? stackoverflow.com/questions/61689720/…
a125

0

En un contexto de componente de clase ...

Si el método changeHandler es una función normal:

handleChange(e){
    this.setState({[e.target.name]:[e.target.value]});
}

se puede usar así ...onChange={(e)=>this.handleChange(e)}

<input type="text" name="any" value={this.state.any} onChange={(e)=>this.handleChange(e)}></input>

Si el método changeHandler es una función de flecha:

handle = (e) =>{
        this.setState({[e.target.name]:[e.target.value]});
    }

se puede usar así ... onChange={this.handle}

 <input type="text" name="any2" value={this.state.any2} onChange={this.handle} ></input>

Y esto resolvió mi problema "No se puede escribir en el campo de entrada de texto de React".

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.