Поле React и Multiple form

Я читал документацию на "onChange" , и мне любопытно, что бы я сделал, если мой форум имеет несколько полей, таких как флажки выбора, флажки, текстовые области и входы? Я просто делаю что-то вроде:

 getInitialState: function() {
    return {textArea: 'Hello!', input: 'World', ...};
  },

в исходное состояние и затем ту же концепцию для обработки этого изменения этого поля?

Ответ 1

Изменить: В ретроспективе этот ответ довольно плох, вместо этого используйте Junle Li.


Да, вы можете сделать именно это. Однако, когда вы получаете много компонентов формы, может быть довольно многословно писать все обработчики и вызовы getInitialState, так как насчет mixin?

jsbin

Обратите внимание, что также посмотрите на значение реакцииLink mixin

Посмотрим, как будет выглядеть наше представление с примером знака в форме. Вы можете вызвать this.getFormData(), чтобы получить объект только с вашим статусом формы, что также позволяет сохранять другие значения в состоянии.

// create a mixin for our form
var formMixin = makeFormMixin([
    "username",
    "password"
]);

var App = React.createClass({
  mixins: [formMixin],
  render: function(){
    return (
      <div>
        <form>
          Username: <input 
                value={this.state.username} 
                onChange={this.handleUsernameChange} />

          Password: <input type="password"
                value={this.state.password} 
                onChange={this.handlePasswordChange} />
        </form>
      </div>
    );
  }
});

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

function makeFormMixin(fields){
  var mixin = {
    getInitialState: function(){
      var state = {};
      fields.forEach(function(field){

        state[field] = this.props[field] || "";
      }, this);
      return state;
    },
    getFormData: function(){
      var data = {};
      fields.forEach(function(field){
        data[field] = this.state[field];
      }, this);
      console.log(data);
      return data;
    }
  };

  fields.forEach(function(field){
    var method = camelJoin(["handle", field, "change"]);
    mixin[method] = function(event){
      var update = {};
      update[field] = event.target.value;
      this.setState(update);
    }
  });

  return mixin;
}

// helper function ["Makes", "things", "camel", "case"] => "makesThingsCamelCase"
function camelJoin(parts){
  return parts.map(function(part, i){
    if (i === 0) {
      return part[0].toLowerCase() + part.slice(1);
    }
    else {
      return part[0].toUpperCase() + part.slice(1);
    }
  }).join("");
}

Ответ 2

@FakeRainBrigand ответ довольно круто.

Я хочу поделиться одним в стиле JavaScript (используйте функцию высокого порядка), гораздо короче:

/** @jsx React.DOM */

var App = React.createClass({
  getInitialState: function () {
    return {
      username: '',
      password: ''
    }
  },
  handleChange: function (key) {
    return function (e) {
      var state = {};
      state[key] = e.target.value;
      this.setState(state);
    }.bind(this);
  },
  render: function(){
    console.log(JSON.stringify(this.getFormData(), null, 4));
    return (
      <div>
        <form>
          Username: <input 
                value={this.state.username} 
                onChange={this.handleChange('username')} />
          <br />
          Password: <input type="password"
                value={this.state.password} 
                onChange={this.handleChange('password')} />
        </form>

        <pre>{JSON.stringify(this.getFormData(), null, 4)}</pre>
      </div>
    );
  }
});

React.renderComponent(<App />, document.body);

Ответ 3

Некоторые из моих друзей обсуждали это сегодня. Решение, предложенное @JunleLi, велико, но оно разбивает Purerender, который заставляет повторно отображать все подкомпоненты каждый раз, когда персонаж, который он ввел в одно из полей, когда он регенерирует функцию.

Вот пример нашего решения. Мы все еще не уверены, полностью ли мы довольны, но в конечном итоге он создает функцию один раз и кэширует ее.

Я хотел бы услышать любую обратную связь.

handleChange(key) {
    if(!this.changeHandlers) this.changeHandlers = {};
    return this.changeHandlers[key] || (this.changeHandlers[key] = event => this.setState({[key]: event.target.value}));
},

render() {
    return (
        <div>
          <input type="text" value={this.state.familyName} onChange={this.handleChange("familyName")} />
          <pre>{JSON.stringify(this.state, null, 4)}</pre>
        </div>
    );
}