Nie można wpisać w polu tekstowym React

111

Próbuję mojego pierwszego fragmentu React.js i jestem zaskoczony ... Mam poniższy kod, który renderuje formularz wyszukiwania na <div id="search"></div> . Ale wpisanie w polu wyszukiwania nic nie daje.

Przypuszczalnie czegoś brakuje podczas przekazywania rekwizytów i stanu w górę iw dół, a to wydaje się być częstym problemem. Ale jestem zaskoczony - nie widzę, czego brakuje.

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

(W końcu będę miał inne rodzaje, SearchFacet*ale próbuję tylko sprawić, by ten działał.)

Phil Gyford
źródło
Spróbuj zarejestrować się thispodczas wprowadzania pola tekstowego. Być może thisnie jest to Searcherjuż składnik.
FaureHu
Dzięki FaureHu - logowanie thisw którym miejscu kodu? Próba zalogowania się Searcher.handleUserInput()lub SearchFacet.handleChange()nic nie daje.
Phil Gyford
możesz zobaczyć moją odpowiedź na podobne pytania. Szczegółowe wyjaśnienie można znaleźć: stackoverflow.com/questions/34713718/…
prudhvi seeramreddi

Odpowiedzi:

80

Nie umieściłeś poprawnie swojego onchangerekwizytu w input. Musi być onChangew formacie JSX.

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

Temat przekazywania właściwości valuedo an <input>, a następnie w jakiś sposób zmienianie wartości przekazywanej w odpowiedzi na interakcję użytkownika za pomocą onChangeprocedury obsługi jest dość dobrze rozważany w dokumentacji .

Odnoszą się do takich danych wejściowych, jak Komponenty kontrolowane , a do danych wejściowych, które zamiast tego pozwalają modelowi DOM natywnie obsługiwać wartość wejściową i późniejsze zmiany wprowadzone przez użytkownika jako Komponenty niekontrolowane .

Ilekroć ustawiasz właściwość valuean inputna jakąś zmienną, masz komponent kontrolowany . Oznacza to, że musisz zmienić wartość zmiennej za pomocą jakichś programowych środków, w przeciwnym razie wejście zawsze będzie zawierało tę wartość i nigdy się nie zmieni, nawet gdy wpiszesz - natywne zachowanie wejścia, aby zaktualizować jego wartość przy wpisywaniu, jest nadpisywane przez React here.

Więc poprawnie pobierasz tę zmienną ze stanu i masz program obsługi, który zaktualizuje stan, wszystko skonfigurowane poprawnie. Problem polegał na tym, że masz onchangei nie poprawny onChangeprogram obsługi nigdy nie był wywoływany, a więc valuenigdy nie był aktualizowany podczas wpisywania danych wejściowych. Kiedy używasz onChangeprogramu obsługi jest wywoływany, value jest aktualizowany podczas wpisywania i widzisz zmiany.

davnicwil
źródło
201

Użycie value={whatever}spowoduje, że nie będzie można wpisywać w polu wejściowym. Powinieneś użyć defaultValue="Hello!".

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

Ponadto, onchangepowinny być onChangejak @davnicwil zaznacza.

Ivan
źródło
2
W moim wymaganiu chciałem, aby pole wejściowe z włączonym wpisywaniem, a także musiało być ustawione na wartość domyślną pochodziło ze zmiennej stanu. Atrybut defaultValue był w porządku, ale występuje problem z aktualizacją wartości domyślnej w zależności od zmian stanu. Czy istnieje sposób na wymuszenie zmiany wartości domyślnej?
semira
1
Powinieneś opublikować ten problem jako kolejne pytanie w Stackoverflow.
Ivan
1
@GeoffreyHale Nie jestem do końca pewien, co masz na myśli, mówiąc, że wprowadza w błąd. Zobacz ten przykład, który nie używa stanu: codepen.io/anon/pen/BQJZwr?editors=0010 . Albo ten, który to robi: codepen.io/anon/pen/JbMJMX?editors=0010
Ivan
4
@Ivan Masz rację, obie są niezmienne: value={whatever}i value={this.state.myvalue}. Zamiast tego powinienem uczynić to wyjaśnienie : używanie onChange={this.handleChange}i cokolwiek podobnego handleChange: function(e) { var newState = {}; newState[e.target.name] = e.target.value; this.setState(newState); },sprawia, że ​​pola są ponownie zmienne.
Geoffrey Hale
1
@Ivan Ten właśnie mi pomógł Dziękuję bardzo, defaultValueocal mój dzień.
Code Cooker
11

Może to być spowodowane tym, że funkcja onChange nie aktualizuje prawidłowej wartości, która jest podana w danych wejściowych.

Przykład:

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

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

w funkcji onChange zaktualizuj wspomniane pole wartości.

sunaina kotekar
źródło
Dzięki, bardzo pomocna. Tylko twoja odpowiedź wyjaśnia w pełni, jak rozwiązać problem.
M3RS
gdzie zdefiniować tę funkcję changeText?
Jitendra Pancholi
Jeśli jest to składnik bezstanowy, wewnątrz funkcji, a jeśli jest to składnik klasy, w konstruktorze.
Gal Grünfeld
nie musisz wpisywać this.state wewnątrz setState. Jeśli napiszesz tylko textValue: event.target.value wewnątrz setState, to również działa idealnie
Pardeep Sharma,
4

Ja też mam ten sam problem iw moim przypadku prawidłowo wtrysnąłem reduktor ale nadal nie mogłem wpisać w pole. Okazuje się, że jeśli używasz immutable, musisz użyć 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 */

Zauważ, że twój stan powinien wyglądać tak, jak w state->formprzeciwnym razie musisz jawnie skonfigurować bibliotekę, a także powinna być nazwa stanu form. zobacz ten problem

Seyed Jalal Hosseini
źródło
4

U mnie następująca prosta zmiana zadziałała idealnie

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

zmień ... wartość = {myPropVal} na ... defaultValue = {myPropVal}

<input type="text" 
        defaultValue={props.letter} 
        onChange={event => setTxtLetter(event.target.value)} /> {/* Works!! */}
Nelles
źródło
To rozwiązało problem. Dzięki!
mikeym
Myślę, że onChange nie działa poprawnie, gdy jest używany w Formiku. Też próbowałem, ale to nie zadziałało. Czy mógłbyś zajrzeć tutaj? stackoverflow.com/questions/61689720/…
a125
0

W kontekście komponentu klasy ...

Jeśli metoda changeHandler jest normalną funkcją:

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

może być używany tak jak ten ...onChange={(e)=>this.handleChange(e)}

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

Jeśli metoda changeHandler jest funkcją strzałkową:

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

można go używać w ten sposób ... onChange={this.handle}

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

I to rozwiązało mój problem „Nie można wpisać pola tekstowego w Reakcie”.

Aditya Patnaik
źródło