• [转]React表单无法输入原因----约束性和非约束性组件


    转自:http://blog.csdn.net/lihongxun945/article/details/46730835

    表单是前端非常重要的一块内容,并且往往包含了错误校验等逻辑。 
    React对表单元素做了专门的优化处理,他对表单元素做了一些抽象,使得他们的使用方式更统一更规范。

    约束性和非约束性组件

    表单里面出来了一个新的概念叫“约束性组件”。那么如何理解约束性组件和非约束性组件呢。

    约束性组件,简单的说,就是由react管理了它的value,而非约束性组件的value就是原生的DOM管理的。 
    他们的写法上也有很大区别。

    非约束性组件这么写:

    <input type="text" defaultValue="a" />
    

    这个 defaultValue 其实就是原生DOM中的 value 属性。这样写出的来的组件,其value值就是用户输入的内容,React完全不管理输入的过程。

    而约束性组件是这么写的:

    <input type="text" value={this.state.name} onChange={this.handleChange} />
    
    //...省略部分代码
    handleChange: function(e) {
      this.setState({name: e.target.value});
    }
    

    这里,value属性不再是一个写死的值,他是 this.state.name,而 this.state.name 是由 this.handleChange 负责管理的。 
    这个时候实际上 input 的 value 根本不是用户输入的内容。而是onChange 事件触发之后,由于 this.setState 导致了一次重新渲染。不过React会优化这个渲染过程,实际它依然是通过设置input的value来实现的。

    但是一定要注意,约束性组件显示的值和用户输入的值虽然很多时候是相同的,但他们根本是两码事。约束性组件显示的是 this.state.name 的值。你可以在handleChange中对用户输入的值做任意的处理,比如你可以做错误校验。

    对比约束性组件和非约束性组件的输入流程:

    • 非约束性组件: 用户输入A -> input 中显示A
    • 约束性组件: 用户输入A -> 触发onChange事件 -> handleChange 中设置 state.name = “A” -> 渲染input使他的value变成A

    正式因为这样,强烈推荐使用约束性组件,因为它能更好的控制组件的生命流程。

    更统一和更规范的接口

    React 把 input,textarea 和 select 三个组件做了抽象和封装,他们的用法变得非常统一,你基本上可以当做同一个组件来用。

    他们现在有统一的 value 属性 和 onChange 事件,现在对于这三种组件你都可以这样写

    <input type='text' name='intro' id='intro' value={this.state.email} onChange={this.handleEmail} />
    <textarea type='text' name='intro' id='intro' value={this.state.intro} onChange={this.handleIntro} />
    <textarea type='text' name='intro' id='intro' value={this.state.intro} onChange={this.handleIntro} />
    

    不过 chekbox有和上面三个不一样,因为checkbox改变的不是 value ,而是 checked 状态。 
    你可以这样写:

    <input type='radio' name='gender' checked={this.state.male} onChange={this.handleGender} value='MALE' />
    <input type='radio' name='gender' checked={!this.state.male} onChange={this.handleGender} value='FEMALE' />
    

    一个示例

    下面是一个包含了 input,textarea, select, radio 的表单,并且做了简单的校验:

      var MyForm = React.createClass({
        getInitialState: function() {
          return {
            email: "",
            intro: "",
            city: "hz",
            male: true, //性别
            emailError: "",
            introError: ""
          };
        },
        handleEmail: function(e) {
          var value = e.target.value;
          var error = '';
          if(!(/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value))) {
            error = '请输入正确的Email';
          }
          this.setState({
            email: value,
            emailError: error
          });
        },
        handleIntro: function(e) {
          var value = e.target.value;
          var error = "";
          if(value.length < 10) {
            error = "介绍不能少于十个字";
          }
          this.setState({
            intro: value,
            introError: error
          });
        },
        handleCity: function(e) {
          var value = e.target.value;
          this.setState({
            city: value,
          });
        },
        handleGender: function(e) {
          var male = !!(e.target.value == 'MALE');
          this.setState({
            male: male
          });
        },
        render: function() {
          return (
            <div>
            <p>
              <label htmlFor='email'>email:</label>
              <input type='text' name='intro' id='intro' value={this.state.email} onChange={this.handleEmail} />
              <span>{this.state.emailError}</span>
            </p>
            <p>
              <label htmlFor='intro'>intro:</label>
              <textarea type='text' name='intro' id='intro' value={this.state.intro} onChange={this.handleIntro} />
              <span>{this.state.introError}</span>
            </p>
            <p>
              <label htmlFor='city'>所在城市:</label>
              <select  name='city' id='city' value={this.state.city} onChange={this.handleCity}>
                <option value='hz'>杭州</option>
                <option value='bj'>北京</option>
                <option value='sh'>上海</option>
              </select>
            </p>
            <p>
              <label>性别:</label>
              <input type='radio' name='gender' checked={this.state.male} onChange={this.handleGender} value='MALE' />
              <input type='radio' name='gender' checked={!this.state.male} onChange={this.handleGender} value='FEMALE' />
            </p>
            </div>
            )
        }
      });
    
      React.render(
        <MyForm />,
        document.getElementById("div1")
        );
  • 相关阅读:
    Python笔记_第一篇_面向过程_第一部分_7.文件的操作(.txt)
    Python笔记_第一篇_面向过程_第一部分_6.语句的嵌套
    Python笔记_第一篇_面向过程_第一部分_6.其他控制语句(with...as等)
    Python笔记_第一篇_面向过程第一部分_6.循环控制语句(while 和 for)_
    Python笔记_第一篇_面向过程_第一部分_6.条件控制语句(if)
    matplot 代码实例
    python下的MySQLdb使用
    vim操作笔记
    使用k-近邻算法改进约会网站的配对效果
    python 读取文本
  • 原文地址:https://www.cnblogs.com/DarkMaster/p/7297788.html
Copyright © 2020-2023  润新知