小编典典

React和多个表单字段

reactjs

我正在阅读有关“
onChange”的文档,
并且对我的论坛有多个字段(例如选择框,复选框,文本区域和输入)会怎么办感到好奇?我是否要做类似的事情:

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

到初始状态,然后使用相同的概念来处理该字段的更改?


阅读 430

收藏
2020-07-22

共1个答案

小编典典

编辑:回想起来,这个答案很糟糕,请改用 Junle Li 的答案。


是的,您可以完全做到这一点。但是,当您获得许多表单组件时,编写所有处理程序和getInitialState调用可能会很冗长,那么mixin呢?

jsbin

注意还请查询react的valueLink混合

让我们看一下示例登录表单后视图的外观。您可以调用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("");
}
2020-07-22