javascript 反应和多个表单字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23985322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 01:55:39  来源:igfitidea点击:

React and Multiple form fields

javascriptreactjs

提问by user3379926

I was reading documentation on "onChange"and I am curious as to what I would do if my forum has multiple fields like select boxes, checkboxes, text areas and inputs? Do I just do something like:

我正在阅读有关“onChange”的文档,我很好奇如果我的论坛有多个字段(如选择框、复选框、文本区域和输入),我会怎么做?我只是做一些类似的事情:

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

to the initial state and then the same concept for handling that change of that field?

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

采纳答案by Brigand

Edit: In retrospect, this answer is pretty bad, use Junle Li's answer instead.

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



Yes you can do exactly that. When you get a lot of form components, though, it can be quite verbose to write all of the handlers and the getInitialState calls, so how about a mixin?

是的,你可以做到这一点。但是,当您获得大量表单组件时,编写所有处理程序和 getInitialState 调用可能会非常冗长,那么 mixin 怎么样呢?

jsbin

jsbin

Note also look up react's valueLink mixin

注意还要查看 react 的 valueLink mixin

Let's take a look at how our view will look with an example sign in form. You can call this.getFormData()to get an object with just your form state, allowing you to store other values in state as well.

让我们通过示例登录表单来看看我们的视图的外观。您可以调用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>
    );
  }
});

This function takes an array of field names, and sets the initial state, and provides handler functions for you. You can then choose to use these, or create your own handler functions for special cases.

该函数接受一个字段名称数组,并设置初始状态,并为您提供处理函数。然后您可以选择使用这些,或为特殊情况创建您自己的处理程序函数。

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("");
}

回答by Junle Li

@FakeRainBrigand 's answer is pretty cool.

@FakeRainBrigand 的回答很酷。

I want to share one in JavaScript style (use high-order function), much shorter:

我想分享一个 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);

回答by mkaatman

Some of my friends were discussing this today. The solution proposed by @JunleLi is great but it breaks Purerender which forces a re-render of all subcomponents every time a character it typed into one of the fields as it is regenerating the function.

今天我的一些朋友正在讨论这个问题。@JunleLi 提出的解决方案很棒,但它破坏了 Purerender,它每次在重新生成函数时将字符输入到一个字段中时都会强制重新渲染所有子组件。

Here is an example of our solution. We're still not sure if we're completely happy with it but it ultimately creates the function once and caches it.

这是我们解决方案的示例。我们仍然不确定我们是否对它完全满意,但它最终会创建一次函数并缓存它。

I'd love to hear any feedback.

我很想听听任何反馈。

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>
    );
}