Не могу ввести текст в поле ввода React

111

Я пробую свою первую часть React.js, и на раннем этапе меня озадачивает ... У меня есть приведенный ниже код, который отображает форму поиска <div id="search"></div>. Но ввод в поле поиска ничего не дает.

Предположительно, что-то не хватает передачи реквизита и состояния вверх и вниз, и это похоже на обычную проблему. Но я в тупике - я не вижу, чего не хватает.

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

(Со временем у меня будут другие типы, SearchFacet*но я просто пытаюсь заставить работать этот.)

Фил Гайфорд
источник
Попробуйте войти, thisкогда вы вводите текстовое поле. Возможно, thisэто уже не Searcherкомпонент.
FaureHu
Спасибо, FaureHu - thisв каком месте кода ведется лог ? Пытаюсь войти Searcher.handleUserInput()или SearchFacet.handleChange()ничего не делает.
Фил Гайфорд
вы можете увидеть мой ответ на похожие вопросы. Вы можете найти подробное объяснение: stackoverflow.com/questions/34713718/…
prudhvi seeramreddi

Ответы:

80

Вы не поместили свою onchangeопору в корпус input. Это должно быть onChangeв JSX.

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

Тема передачи valueопоры в объект <input>и последующего изменения значения, передаваемого в ответ на взаимодействие с пользователем с помощью onChangeобработчика, довольно хорошо рассматривается в документации .

Они относятся к таким входам как контролируемые компоненты и относятся к входам, которые вместо этого позволяют модели DOM изначально обрабатывать входные значения и последующие изменения от пользователя как неконтролируемые компоненты .

Всякий раз, когда вы устанавливаете valueопору inputнекоторой переменной, у вас есть управляемый компонент . Это означает, что вы должны изменить значение переменной какими-то программными средствами, иначе вход всегда будет содержать это значение и никогда не изменится, даже когда вы печатаете - собственное поведение входа, чтобы обновить его значение при вводе, переопределяется от React здесь.

Итак, вы правильно берете эту переменную из состояния и имеете обработчик для обновления состояния, все настроено нормально. Проблема заключалась в том, что у вас есть, onchangeа не правильный onChangeобработчик, который никогда не вызывался, и поэтому valueникогда не обновлялся при вводе ввода. Когда вы используете onChangeобработчик будет вызван, value будет обновляться при вводе, и вы увидите изменения.

Давниквиль
источник
201

Использование value={whatever}приведет к тому, что вы не сможете вводить текст в поле ввода. Вам следует использовать defaultValue="Hello!".

См. Https://facebook.github.io/react/docs/uncontrolled-components.html#default-values.

Кроме того, onchangeдолжно быть, onChangeкак указывает @davnicwil.

Иван
источник
2
В моем требовании я хотел ввести поле ввода с включением ввода, так как для него необходимо установить значение по умолчанию, полученное из переменной состояния. Атрибут defaultValue в порядке, но есть проблема с обновлением значения по умолчанию в соответствии с изменениями состояния, есть ли способ принудительно изменить значение по умолчанию?
Semira
1
Вы должны опубликовать эту проблему как еще один вопрос на Stackoverflow.
Иван
1
@GeoffreyHale Я не совсем понимаю, что вы имеете в виду, говоря, что это вводит в заблуждение. См. Этот пример, в котором состояние не используется: codepen.io/anon/pen/BQJZwr?editors=0010 . Или тот, который делает: codepen.io/anon/pen/JbMJMX?editors=0010
Иван
4
@Ivan Вы правы, оба неизменны: value={whatever}и value={this.state.myvalue}. Вместо этого я должен был сделать это уточнение : использование onChange={this.handleChange}и что-нибудь подобное handleChange: function(e) { var newState = {}; newState[e.target.name] = e.target.value; this.setState(newState); },снова делает поля изменяемыми.
Джеффри Хейл,
1
@Ivan Этот только что помог мне, большое спасибо, defaultValueспасла меня.
Code
11

Это может быть вызвано тем, что функция onChange не обновляет правильное значение, указанное во входных данных.

Пример:

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

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

в функции onChange обновите указанное поле значения.

Сунаина Котекар
источник
Спасибо, очень помогли. Только ваш ответ полностью объясняет, как решить проблему.
M3RS
где определить эту функцию changeText?
Джитендра Панчоли
Если это компонент без состояния, внутри функции, а если это компонент класса, внутри конструктора.
Гал Грюнфельд
вам не нужно писать this.state внутри setState. Если вы пишете textValue: event.target.value внутри setState, он также отлично работает
Пардип Шарма
4

У меня также есть такая же проблема, и в моем случае я правильно ввел редуктор, но все же я не мог ввести поле. Оказывается, если вы используете, immutableвы должны использовать 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 */

Обратите внимание, что ваше состояние должно быть таким, как state->formиначе, вы должны явно настроить библиотеку, а также имя для состояния form. увидеть эту проблему

Сейед Джалал Хоссейни
источник
4

Для меня следующее простое изменение сработало отлично

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

измените ... value = {myPropVal} на ... defaultValue = {myPropVal}

<input type="text" 
        defaultValue={props.letter} 
        onChange={event => setTxtLetter(event.target.value)} /> {/* Works!! */}
Nelles
источник
Это исправило это для меня. Спасибо!
mikeym
Я думаю, что onChange не работает должным образом при использовании в Formik. Я тоже пробовал это, но у меня это не сработало. Не могли бы вы взглянуть сюда? stackoverflow.com/questions/61689720/…
a125
0

В контексте компонента класса ...

Если метод changeHandler - обычная функция:

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

его можно использовать вот так ...onChange={(e)=>this.handleChange(e)}

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

Если метод changeHandler является стрелочной функцией:

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

его можно использовать вот так ... onChange={this.handle}

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

И это решило мою проблему «Не могу ввести текст в поле ввода React».

Адитья Патнаик
источник