Вопрос по reactjs, javascript – React.js: идентификация различных входных данных с помощью одного обработчика onChange

125

Любопытно, как правильно подойти к этому:

var Hello = React.createClass({
getInitialState: function() {
    return {total: 0, input1:0, input2:0};
},
render: function() {
    return (
        {this.state.total}<br>
            
            
        
    );
},
handleChange: function(e){
    this.setState({ ??? : e.target.value});
    t = this.state.input1 + this.state.input2;
    this.setState({total: t});
}
});

React.renderComponent(, document.getElementById('content'));

Очевидно, что вы можете создать отдельные функции handleChange для обработки каждого отдельного ввода, но этоне очень приятно. Точно так же вы можете создать компонент только для отдельного ввода, но я хотел посмотреть, есть лиЭто способ сделать это так.

Ваш Ответ

9   ответов
144

таких какname наinput Элементы для определения ваших входов. Кроме того, вы ненадо держать "Всего" как отдельное значение в состоянии, потому что оно может быть составлено путем добавления других значений в вашем состоянии:

var Hello = React.createClass({
    getInitialState: function() {
        return {input1: 0, input2: 0};
    },
    render: function() {
        const total = this.state.input1 + this.state.input2;

        return (
            <div>{total}<br>
                <input type="text" value="{this.state.input1}" name="input1" onchange="{this.handleChange}">
                <input type="text" value="{this.state.input2}" name="input2" onchange="{this.handleChange}">
            </div>
        );
    },
    handleChange: function(e) {
        this.setState({[e.target.name]: e.target.value});
    }
});

React.renderComponent(<hello>, document.getElementById('content'));
</hello>
Если ты'повторное использованиеname для чего-то другого, вы можете использоватьdata атрибуты вместо Например,data-input-name="input1" и получить к нему доступ сe.target.dataset.inputName LaurelB
Спасибо за это. очень простой способ сделать Я попробовал то же самое, но это была ошибка синтаксиса, затем увидел ваш ответ, это было просто объявить как объект. Gaurravs
@ericgrosse Согласен, я бы не сталЯ предлагаю это для всех слушателей событий, но все элементы формыonchange и имеютname атрибутов. Если вы создаете простой старый HTML-форму без JavaScript,name идентифицирует элементы формы, когда этос представленными. Я предлагаю придерживаться стандартной функциональности формы. Ross Allen
Использование связывания - лучший подход. Этот подход неЭто не сработает, если вы присоедините обработчик onChange к элементу без свойства name, например, div. ericgrosse
5

Вы также можете сделать это так:

...
constructor() {
    super();
    this.state = { input1: 0, input2: 0 };
    this.handleChange = this.handleChange.bind(this);
}

handleChange(input, value) {
    this.setState({
        [input]: value
    })
}

render() {
    const total = this.state.input1 + this.state.input2;
    return (
        <div>
            {total}<br>
            <input type="text" onchange="{e" ==""> this.handleChange('input1', e.target.value)} />
            <input type="text" onchange="{e" ==""> this.handleChange('input2', e.target.value)} />
        </div>
    )
}
А не было»Т работал на меня. увидел React инструменты разработчика. его создание и присвоение значений переменной / объекту, называемому input, вместо input1 / input2 Gaurravs
@Gaurravs да, тыверно. Мне нужно было добавить[] вокругinput в setState. Это делает свойство динамически назначенным inostia
прохладно. сейчас работает Gaurravs
0

Когда дело доходит до форм с несколькими полями, имеет смысл использовать React 'Ключевая особенность: компоненты.

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

[...]

handleChange: function(event) {
  this.setState({value: event.target.value});
},
render: function() {
  var value = this.state.value;
  return <input type="text" value="{value}" onchange="{this.handleChange}">;
}

[...]
4

Вы можете использовать специальныйReact атрибут называетсяref а затем сопоставить реальные DOM-узлы вonChange событие с использованиемReactgetDOMNode() функция:

handleClick: function(event) {
  if (event.target === this.refs.prev.getDOMNode()) {
    ...
  }
}

render: function() {
  ...
  <button ref="prev" onclick="{this.handleClick}">Previous question</button>
  <button ref="next" onclick="{this.handleClick}">Next question</button>
  ...
}
Начиная с React v0.14, вы можете просто сделать.event.target === this.refs.prevfacebook.github.io/react/blog/2015/10/07/... XåpplI'-I0llwlg'I -
По крайней мере в 0.13 this.refs не делаетт есть свойство прив. usagidon
@usagidon -prev это просто имя, которое я установил вrender() метод Janusz Kacalak
11
Устаревшее решение

valueLink/checkedLink являютсяосуждается от ядра React, потому что это сбивает с толку некоторых пользователей. Этот ответ выигралне работает, если вы используете последнюю версию React. Но если вам это нравится, вы можете легко подражать ему, создавая свой собственныйInput составная часть

Старый ответ содержание:

То, чего вы хотите достичь, может быть достигнуто гораздо проще с помощью двухсторонних помощников связывания данных React.

var Hello = React.createClass({
    mixins: [React.addons.LinkedStateMixin],
    getInitialState: function() {
        return {input1: 0, input2: 0};
    },

    render: function() {
        var total = this.state.input1 + this.state.input2;
        return (
            <div>{total}<br>
                <input type="text" valuelink="{this.linkState('input1')}">;
                <input type="text" valuelink="{this.linkState('input2')}">;
            </div>
        );
    }

});

React.renderComponent(<hello>, document.getElementById('content'));
</hello>

Легко ли?

http://facebook.github.io/react/docs/two-way-binding-helpers.html

Вы можете дажереализовать свой собственный миксин

Обратите внимание, что это решение устарело Philipp
Почему мы должны связать onchange, чтобы установить состояние. Это'ReactJS в конце концов! Junaid Qadir
105

Вы можете использовать.bind метод предварительной сборки параметров вhandleChange метод. Это было бы что-то вроде:

  var Hello = React.createClass({
    getInitialState: function() {
        return {input1:0, 
                input2:0};
    },
    render: function() {
      var total = this.state.input1 + this.state.input2;
      return (
        <div>{total}<br>
          <input type="text" value="{this.state.input1}" onchange="{this.handleChange.bind(this," 'input1')}="">
          <input type="text" value="{this.state.input2}" onchange="{this.handleChange.bind(this," 'input2')}="">
        </div>
      );
    },
    handleChange: function (name, e) {
      var change = {};
      change[name] = e.target.value;
      this.setState(change);
    }
  });

  React.renderComponent(<hello>, document.getElementById('content'));
</hello>

(Я также сделалtotal вычисляться во время рендеринга, как это рекомендуется делать.)

Если вы измените реализациюhandleChange вhandleChange(name) { return event => this.setState({name: event.target.value}); } ты можешь пройтитак же" функция (выиграл 'не может создать новую функциюсделано с помощью.bind() Затем вы можете передать такую функцию:this.handleChange("input1") Andreyco
Просто быстрое напоминание о том, чтоthis.handleChange.bind(...) создает новую функцию. Если тыповторное использованиеshouldComponentUpdate сPureRenderMixin или что-то подобное оно сломается. Все ваши входные компоненты будут перерисованы при изменении одного значения. zemirco
Я думаю, что также важно упомянуть, что природа setState заключается в том, что вы не сможете получить текущее состояние в функции handChange, но используйте предыдущее состояние, например this.state.input1. Правильный подход заключается в создании обратного вызова, такого какthis.setState(change, function () { console.log(this.state.input1); ); ссылка:stackoverflow.com/questions/30782948/... Master-Chief
37

onChange событие пузыри ... Так что вы можете сделать что-то вроде этого:

// A sample form
render () {
  <form onchange="{setField}">
    <input name="input1">
    <input name="input2">
  </form>
}

И ваш метод setField может выглядеть следующим образом (если выповторное использование ES2015 или более поздней версии:

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

Я использую нечто подобное в нескольких приложениях, и этодовольно удобно.

довольно чистое решение. благодарю вас Gaurravs
-1

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

var Hello = React.createClass({
    render: function() {
        var total = this.state.input1 + this.state.input2;
        return (
             <div>{total}<br>
                  <input type="text" value="{this.state.input1}" id="input1" onchange="{this.handleChange}">
                 <input type="text" value="{this.state.input2}" id="input2" onchange="{this.handleChange}">
            </div>
       );
   },
   handleChange: function (name, value) {
       var change = {};
       change[name] = value;
       this.setState(change);
   }
});

React.renderComponent(<hello>, document.getElementById('content'));
</hello>
0

Вы можете отслеживать ценность каждого ребенкаinput создав отдельныйInputField компонент, который управляет стоимостью одногоinput, Например,InputField может быть:

var InputField = React.createClass({
  getInitialState: function () {
    return({text: this.props.text})
  },
  onChangeHandler: function (event) {
     this.setState({text: event.target.value})
  }, 
  render: function () {
    return (<input onchange="{this.onChangeHandler}" value="{this.state.text}">)
  }
})

Теперь ценность каждогоinput можно отслеживать в отдельном экземпляре этогоInputField компонент без создания отдельных значений в родительскомСостояние для контроля каждого дочернего компонента.

Похожие вопросы