Не могу ввести текст в поле ввода 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!! */}

Это исправило это для меня. Спасибо!
— 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».

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.