Подтвердить что ты не робот

Как получить значение поля ввода с помощью ReactJS?

У меня есть следующий компонент React:

export default class MyComponent extends React.Component {

    onSubmit(e) {
        e.preventDefault();
        var title = this.title;
        console.log(title);
    }

    render(){
        return (
            ...
            <form className="form-horizontal">
                ...
                <input type="text" className="form-control" ref={(c) => this.title = c} name="title" />
                ...
            </form>
            ...
            <button type="button" onClick={this.onSubmit} className="btn">Save</button>
            ...
        );
    }

};

Консоль дает мне undefined - любые идеи, что не так с этим кодом?

4b9b3361

Ответ 1

Вы должны использовать конструктор под классом MyComponent extends React.Component

constructor(props){
    super(props);
    this.onSubmit = this.onSubmit.bind(this);
  }

Тогда вы получите результат заголовка

Ответ 2

Здесь есть три ответа, в зависимости от версии React, с которой вы (вынуждены) работать (ing), и от того, хотите ли вы использовать хуки.

Перво-наперво:

Важно понимать, как работает React, чтобы вы могли все делать правильно (подсказка: очень полезно пройти учебное упражнение React на веб-сайте React. Оно хорошо написано и охватывает все основы так, как на самом деле объясняется, как это сделать. вещи). "Правильно" здесь означает, что вы пишете интерфейс приложения, который отображается в браузере; вся работа с интерфейсом происходит в React, а не в "том, к чему вы привыкли, когда пишете веб-страницу" (именно поэтому приложения React являются "приложениями", а не "веб-страницами").

Приложения React отображаются на основе двух вещей:

  1. свойства компонента, объявленные любым родительским объектом, создают экземпляр этого компонента, который родитель может изменять на протяжении всего своего жизненного цикла, и
  2. собственное внутреннее состояние компонента, которое он может изменять самостоятельно в течение всего своего жизненного цикла.

То, что вы явно не делаете, когда используете React, - это генерирование элементов HTML, а затем их использование: когда вы говорите React, например, использовать <input>, вы не создаете элемент ввода HTML, вы говорите React создать Реагировать на объект ввода, который отображается как элемент ввода HTML и чья обработка событий просматривает, но не контролируется событиями ввода элемента HTML.

При использовании React вы создаете элементы пользовательского интерфейса приложения, которые предоставляют пользователю (часто манипулируемые) данные, когда взаимодействие с пользователем изменяет состояние компонента, что может вызвать повторное отображение части интерфейса вашего приложения, чтобы отразить новое состояние. В этой модели состояние всегда является окончательным авторитетом, а не "какой бы библиотекой пользовательского интерфейса ни использовался для его визуализации", а в Интернете это DOM браузера. DOM - это почти запоздалая мысль в этой модели программирования: это просто конкретная среда пользовательского интерфейса, которую использует React.

Таким образом, в случае элемента ввода логика:

  1. Вы вводите элемент ввода
  2. с вашим элементом ввода пока ничего не происходит, событие было перехвачено React и немедленно прервано,
  3. React перенаправляет событие в функцию, настроенную для обработки событий,
  4. эта функция может запланировать обновление состояния,
  5. если это произойдет, React выполнит это обновление состояния (асинхронно!) и вызовет вызов render после обновления, но только если обновление состояния изменило состояние.
  6. только после этого рендеринга пользовательский интерфейс покажет, что вы "набрали букву".

Все это происходит за считанные миллисекунды, если не меньше, поэтому похоже, что вы вводили элемент ввода точно так же, как вы привыкли к тому, что "просто используете элемент ввода на странице", но это совершенно не то, что произошло.

Итак, с учетом сказанного о том, как получить значения из элементов в React:

Реагируйте 15 и ниже с ES5

Чтобы сделать все правильно, у вашего компонента есть значение состояния, которое отображается через поле ввода, и мы можем обновить его, заставив этот элемент пользовательского интерфейса отправлять события изменения обратно в компонент:

var Component = React.createClass({
  getInitialState: function() {
    return {
      inputValue: ''
    };
  },

  render: function() {
    return (
      //...
      <input value={this.state.inputValue} onChange={this.updateInputValue}/>
      //...
    );
  },

  updateInputValue: function(evt) {
    this.setState({
      inputValue: evt.target.value
    });
  }
});

Итак, мы говорим React использовать функцию updateInputValue для обработки взаимодействия с пользователем, использовать setState для планирования обновления состояния, а тот факт, что render подключается к this.state.inputValue, означает, что когда он повторяется после обновления состояние, пользователь увидит текст обновления в зависимости от того, что они ввели.

приложение на основе комментариев

Учитывая, что входные данные пользовательского интерфейса представляют значения состояния (рассмотрим, что произойдет, если пользователь закрывает свою вкладку на полпути, и вкладка восстанавливается. Должны ли быть восстановлены все эти значения, заполненные им? Если это так, то это состояние). Это может заставить вас чувствовать, что для большой формы требуются десятки или даже сотни форм ввода, но React - это моделирование вашего пользовательского интерфейса в удобной для обслуживания форме: у вас нет 100 независимых полей ввода, у вас есть группы связанных входов, поэтому вы фиксируете каждую из них. сгруппируйте в компонент, а затем создайте свою "основную" форму как набор групп.

MyForm:
  render:
    <PersonalData/>
    <AppPreferences/>
    <ThirdParty/>
     ...

Это также гораздо проще поддерживать, чем гигантский компонент с одной формой. Разделите группы на Компоненты с поддержкой состояния, где каждый компонент отвечает только за отслеживание нескольких полей ввода одновременно.

Вы также можете почувствовать себя "хлопотно" по написанию всего этого кода, но это ложная экономия: разработчики, которые не являются вами, включая вас в будущем, на самом деле очень выигрывают от того, что все эти входные данные явно подключены, потому что это значительно упрощает отслеживание путей кода. Тем не менее, вы всегда можете оптимизировать. Например, вы можете написать компоновщик состояния

MyComponent = React.createClass({
  getInitialState() {
    return {
      firstName: this.props.firstName || "",
      lastName: this.props.lastName || "" 
      ...: ...
      ...
    }
  },
  componentWillMount() {
    Object.keys(this.state).forEach(n => {
      let fn = n + 'Changed';
      this[fn] = evt => {
        let update = {};
        update[n] = evt.target.value;
        this.setState(update);
      });
    });
  },
  render: function() {
    return Object.keys(this.state).map(n => {
      <input
        key={n} 
        type="text"
        value={this.state[n]}
        onChange={this[n + 'Changed']}/>
    });
  }
});

Конечно, есть улучшенные версии этого, поэтому ищите https://npmjs.com и ищите решение по связыванию состояний React, которое вам больше нравится. Open Source - это в основном поиск того, что уже сделали другие, и использование этого вместо того, чтобы писать все с нуля.

Реакция 16 (и 15,5 переходных) и "современный" JS

Начиная с React 16 (и мягкого запуска с 15.5), вызов createClass больше не поддерживается, и необходимо использовать синтаксис класса. Это меняет две вещи: очевидный синтаксис класса, но также привязку контекста this, которую createClass может делать "бесплатно", поэтому, чтобы убедиться, что все работает, убедитесь, что вы используете нотацию "жирной стрелки" для this сохраняющие контекст анонимные функции в обработчиках onWhatever, таких как onChange, который мы используем в коде здесь:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: ''
    };
  }

  render() {
    return (
      //...
      <input value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)}/>
      //...
    );
  },

  updateInputValue(evt) {
    this.setState({
      inputValue: evt.target.value
    });
  }
});

Возможно, вы также видели, как люди использовали bind в своем конструкторе для всех своих функций обработки событий, например:

constructor(props) {
  super(props);
  this.handler = this.handler.bind(this);
  ...
}

render() {
  return (
    ...
    <element onclick={this.handler}/>
    ...
  );
}

Не делай этого.

Практически каждый раз, когда вы используете bind, применяется общеизвестное "вы делаете это неправильно". Ваш класс уже определяет прототип, и, следовательно, модель программирования уже определяет контекст экземпляра. Не ставьте bind сверх того, чтобы использовать обычную пересылку событий вместо дублирования всех ваших вызовов функций в конструкторе. Теперь вы увеличили поверхность ошибки и усложнили отслеживание ошибок, потому что проблема может быть в вашем конструкторе, а не в том месте, где вы вызываете свой код. В дополнение к тому, что вам приходится работать с другими, с кем вы работаете (или хотите).

Да, я знаю, что реагирующие документы говорят это хорошо. Это не так, не делай этого.

Реагируйте на 16.8, используя функциональные компоненты с крючками

Начиная с React 16.8 компоненту функции (т.е. буквально просто функции, которая принимает некоторый props в качестве аргумента, можно использовать, как если бы он являлся экземпляром класса компонента, без написания какого-либо класса), также можно придать состояние посредством использования крюки.

Если вам не нужен полный код класса, и подойдет одна функция экземпляра, то теперь вы можете использовать хук useState, чтобы получить единственную переменную состояния и ее функцию обновления, которая работает примерно так же, как и в приведенных выше примерах., кроме как без вызова функции setState:

import { useState } from 'react';

function myFunctionalComponentFunction() {
  const [input, setInput] = useState(''); // '' is the initial state value
  return (
    <div>
    <label>Please specify:</label>
    <input value={input} onInput={e => setInput(e.target.value)}/>
    </div>
  );
}

Раньше неофициальное различие между классами и компонентами функций заключалось в том, что "функциональные компоненты не имеют состояния", поэтому мы больше не можем скрывать это: разницу между компонентами функций и компонентами классов можно найти на нескольких страницах. очень хорошо написанную документацию по реагированию (без краткого пояснения, которое удобно для вас неправильно истолковывать!), которую вы должны прочитать, чтобы знать, что вы делаете, и, таким образом, знать, выбрали ли вы лучшее (что бы вы ни выбрали) это означает для вас) решение, чтобы запрограммировать себя на проблему, с которой вы столкнулись.

Ответ 3

Удалось получить значение поля ввода, выполнив что-то вроде этого:

import React, { Component } from 'react';

class App extends Component {

constructor(props){
super(props);

this.state = {
  username : ''
}

this.updateInput = this.updateInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}


updateInput(event){
this.setState({username : event.target.value})
}


handleSubmit(){
console.log('Your input value is: ' + this.state.username)
//Send state to the server code
}



render(){
return (
    <div>
    <input type="text" onChange={this.updateInput}></input>
    <input type="submit" onClick={this.handleSubmit} ></input>
    </div>
  );
}
} 

//output
//Your input value is: x

Ответ 4

В реакции 16 я использую

<Input id="number" 
       type="time" 
       onChange={(evt) => { console.log(evt.target.value); }} />

Ответ 5

Мне удалось это сделать, привязав "this" к функции updateInputValue (evt) с

this.updateInputValue = this.updateInputValue.bind(this);

Однако входное value = {this.state.inputValue}... оказалась не очень хорошей идеей.

Здесь полный код в babel ES6:

class InputField extends React.Component{


  constructor(props){
   super(props);
   //this.state={inputfield: "no value"};   
   this.handleClick = this.handleClick.bind(this);
   this.updateInputValue = this.updateInputValue.bind(this);
  }

  handleClick(){
   console.log("trying to add picture url");
   console.log("value of input field : "+this.state.inputfield);

  }

  updateInputValue(evt){
    //console.log("input field updated with "+evt.target.value);
    this.state={inputfield: evt.target.value};   

  }

  render(){
    var r; 
    r=<div><input type="text" id="addpixinputfield" 
            onChange={this.updateInputValue} />
      <input type="button" value="add" id="addpix" onClick={this.handleClick}/>
      </div>;    
    return r;
   }
}

Ответ 6

ваша ошибка связана с тем, что вы используете класс, а когда используете класс, нам нужно связать функции с этим, чтобы хорошо работать. во всяком случае, есть много уроков, почему мы должны "this" и что "this" делать в javascript.

если вы исправите кнопку отправки, это должно быть:

<button type="button" onClick={this.onSubmit.bind(this)} className="btn">Save</button>

а также если вы хотите показать значение этого ввода в консоли, вы должны использовать var title= this.title.value;

Ответ 7

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

Просто добавьте элемент ввода a 'ref attr:

И затем используйте this.refs, чтобы получить входное значение, когда вам это нужно.

Ответ 8

// On the state
constructor() {
  this.state = {
   email: ''
 }
}

// Input view ( always check if property is available in state {this.state.email ? this.state.email : ''}

<Input 
  value={this.state.email ? this.state.email : ''} 
  onChange={event => this.setState({ email: event.target.value)}
  type="text" 
  name="emailAddress" 
  placeholder="[email protected]" />