React学习之独特的表单(八)

在众多HTML标签元素中,Form表单在ReactHTML中使用是不同,比如如下HTML表单:

<form>
  <label>
    Name:
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>

上述代码会在视图中形成一个表单,并让用户提交表单数据,但是如果这份代码直接写在React中的话,那就真的只是个表单,但是实际上我们还需要进行很多其他的操作,比如提交表单时的数据合理性检测啊,对用户数据进行处理更新,等等…

所以,每当我们要用到表单的时候,我们会进行很多处理,以至于要绑定一些函数来处理数据,这种在React对组件进行数据监测处理,以及函数绑定的机制或者说有这种功能的组件称为“组件控制”或者“控制式组件”

1.控制型组件为何物

即是对组件的控制,说来也是之前讲事件绑定时的东西,通过为组件绑定事件实现组件的控制,当然我也说了我们绑定组件必须绑定在DOM标签上,否则是不起作用的

通过组件控制我们可以控制用户的输入

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleChange(event) {
    this.setState({value: event.target.value});
  }
  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
ReactDOM.render(
    <NameForm />,
    document.getElementById('root')
    );

简简单单的更改数据处理方式就会有不一样的体验,比如将handleChange的数据处理改一下,就可以实现数据默认大写化

handleChange(event) {
  this.setState({value: event.target.value.toUpperCase()});
}

textarea标签

textarea一般可以直接在它的标签内进行设置,如下:

<textarea>
  Hello there, this is some text in a text area
</textarea>

而我们React可以通过value属性来控制它的值

class EssayForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 'Please write an essay about your favorite DOM element.'
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleChange(event) {
    this.setState({value: event.target.value.toUpperCase()});
  }
  handleSubmit(event) {
    alert('An essay was submitted: ' + this.state.value);
    event.preventDefault();
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <textarea value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
ReactDOM.render(
    <EssayForm />,
    document.getElementById('root')
    );

select标签

HTMLselect标签会创建一个下拉列表,我们通过为optionselected来选择。

<select>
  <option value="grapefruit">Grapefruit</option>
  <option value="lime">Lime</option>
  <option selected value="coconut">Coconut</option>
  <option value="mango">Mango</option>
</select>

其中会选择coconut,同样的在React中我们可以直接通过value的属性进行控制

class FlavorForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 'coconut'};
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleChange(event) {
    this.setState({value: event.target.value});
  }
  handleSubmit(event) {
    alert('Your favorite flavor is: ' + this.state.value);
    event.preventDefault();
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Pick your favorite La Croix flavor:
          <select value={this.state.value} onChange={this.handleChange}>
            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

总结

对于<input type="text"><textarea><select>React中的使用是非常类似的,他们都可以通过一个value属性让我们实现组件的控制(对他们的数据进行处理),而type="checkbox"type="number"等得需要按照需求处理

2.处理多个输入

如果你需要处理多个输入的话,你可能需要为input元素绑定一些属性来标记是哪一个元素,当然也可以不标记(前提是你对每一个input使用的是不相同的函数,如果是相同的元素是必须标记的,否则不知道如何处理)

而实际上我们对于这个标记的方法都是固定,原因就是我们使用表单元素,每一个提交给后台的数据一定有一个name属性,所以我们一般用inputname属性来标识不同的input元素,如下:

class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };
    this.handleInputChange = this.handleInputChange.bind(this);
  }
  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

    this.setState({
      [name]: value
    });
  }
  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}

其中的

this.setState({
      [name]: value
    });

是属于ES6的语法,用于将name中的值作为对象的属性,而不是用name当做其对象,上述等价:

var partialState = {};
partialState[name] = value;
this.setState(partialState);

如果大家不了解,可以去看ES6的对象部分

不足

大家应该也知道上述的控制型组件会存在一个问题,如果我们融合一个外部的类库或者插件到React会很麻烦,让我们非常的郁闷,所以React提供了非控制式组件用来给我们解决融合外部插件时的问题。

下一篇博客将讲React构造最近祖先状态

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值