Impossibile digitare nel campo di testo di input di React


111

Sto provando il mio primo bit di React.js e sono perplesso all'inizio ... Ho il codice qui sotto, che rende un modulo di ricerca in <div id="search"></div>. Ma la digitazione nella casella di ricerca non fa nulla.

Presumibilmente sta perdendo qualcosa passando gli oggetti di scena e lo stato su e giù, e questo sembra un problema comune. Ma sono perplesso: non riesco a vedere cosa manca.

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

(Alla fine avrò altri tipi di SearchFacet*ma sto solo cercando di farlo funzionare.)


Prova ad accedere thisquando inserisci il campo di testo. Potrebbe essere che thisnon sia più il Searchercomponente.
FaureHu

Grazie FaureHu. thisA quale punto del codice ti stai registrando ? Il tentativo di accedere Searcher.handleUserInput()o SearchFacet.handleChange()non fa nulla.
Phil Gyford

puoi vedere la mia risposta per domande simili. Si possono trovare spiegazione dettagliata: stackoverflow.com/questions/34713718/...
prudhvi seeramreddi

Risposte:


80

Non hai adeguatamente rivestito il tuo onchangepuntello nel file input. Deve essere onChangein JSX.

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

L'argomento del passaggio di un oggetto di valuescena a un <input>e quindi in qualche modo la modifica del valore passato in risposta all'interazione dell'utente utilizzando un onChangegestore è abbastanza ben considerato nei documenti .

Si riferiscono a tali input come componenti controllati e si riferiscono a input che invece consentono al DOM di gestire in modo nativo il valore dell'input e le successive modifiche dell'utente come componenti non controllati .

Ogni volta che imposti la valueprop di una inputsu una variabile, hai una componente controllata . Ciò significa che devi modificare il valore della variabile con alcuni mezzi programmatici, altrimenti l'input manterrà sempre quel valore e non cambierà mai, anche quando digiti: il comportamento nativo dell'input, per aggiornare il suo valore durante la digitazione, viene sovrascritto di React here.

Quindi, stai prendendo correttamente quella variabile dallo stato e hai un gestore per aggiornare lo stato tutto impostato correttamente. Il problema era perché hai onchangee non la corretta onChangeil gestore non è mai stato chiamato e quindi valuenon è mai stato aggiornato quando digiti nell'input. Quando si utilizza viene chiamato onChangeil gestore , viene aggiornato quando si digita e vengono visualizzate le modifiche.value


201

Usando value={whatever}lo farà in modo da non poter digitare nel campo di input. Dovresti usare defaultValue="Hello!".

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

Inoltre, onchangedovrebbe essere onChangecome sottolinea @davnicwil.


2
Nel mio requisito volevo inserire il campo con l'abilitazione alla digitazione e deve essere impostato sul valore predefinito proveniente da una variabile di stato. L'attributo defaultValue andava bene ma c'è un problema nell'aggiornamento del valore predefinito in base ai cambiamenti di stato, c'è un modo per forzare la modifica del valore predefinito?
semira

1
Dovresti pubblicare questo problema come un'altra domanda su Stackoverflow.
Ivan

1
@GeoffreyHale Non sono abbastanza sicuro di cosa intendi per come sia fuorviante. Guarda questo esempio che non utilizza lo stato: codepen.io/anon/pen/BQJZwr?editors=0010 . O questo che fa: codepen.io/anon/pen/JbMJMX?editors=0010
Ivan

4
@Ivan Hai ragione, entrambi sono immutabili: value={whatever}e value={this.state.myvalue}. Avrei dovuto invece fare questa precisazione : usare onChange={this.handleChange}e qualcosa di simile handleChange: function(e) { var newState = {}; newState[e.target.name] = e.target.value; this.setState(newState); },rende di nuovo mutabili i campi.
Geoffrey Hale

1
@Ivan Questo mi ha appena aiutato Grazie mille a defaultValuesalvarmi la giornata.
Code Cooker

11

Ciò potrebbe essere causato dalla funzione onChange che non aggiorna il valore corretto menzionato nell'input.

Esempio:

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

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

nella funzione onChange aggiorna il campo del valore menzionato.


Grazie, molto utile. Solo la tua risposta spiega per intero come risolvere il problema.
M3RS

dove definire questa funzione changeText?
Jitendra Pancholi

Se è un componente senza stato, all'interno della funzione e se è un componente di classe, all'interno del costruttore.
Gal Grünfeld

non è necessario scrivere this.state all'interno di setState. Se scrivi solo textValue: event.target.value all'interno di setState, funziona perfettamente
Pardeep Sharma

4

Anch'io ho lo stesso problema e nel mio caso ho iniettato correttamente il riduttore ma non riuscivo ancora a digitare nel campo. Si scopre che se stai usando immutabledevi usare 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 */

Nota che il tuo stato dovrebbe essere come state->formaltrimenti devi configurare esplicitamente la libreria anche il nome per lo stato dovrebbe essere form. vedere questo problema


4

Per me la seguente semplice modifica ha funzionato perfettamente

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

cambia ... value = {myPropVal} in ... defaultValue = {myPropVal}

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

Questo ha risolto il problema per me. Grazie!
mikeym

Penso che onChange non funzioni correttamente se utilizzato in Formik. Stavo provando anche questo, ma non ha funzionato per me. Potresti dare un'occhiata qui? stackoverflow.com/questions/61689720/...
A125

0

In un contesto di componente di classe ...

Se il metodo changeHandler è una funzione normale:

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

può essere usato in questo modo ...onChange={(e)=>this.handleChange(e)}

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

Se il metodo changeHandler è una funzione freccia:

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

può essere usato così ... onChange={this.handle}

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

E questo ha risolto il mio problema "Impossibile digitare nel campo di testo di input di React".

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.