表单

受控组件

在 HTML 中,表单元素(如<input><textarea><select>)通常自己维护 state,并根据用户输入进行更新。而在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState()来更新。

定义:使 React 的 state 成为组件的“唯一数据源”。渲染表单的 React 组件并控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。

示例:

// 该示例将表单里用到的几乎都列出来了
state = {
  username: "",
  password: "",
  select: "老师",
  radio: '1',
  textarea: ""
}

handleChange = ({target}) => {
  // 处理checkes的值
    const setCheckes = (target) => {
      // state是只读的,不能直接修改,赋给一个变量后就可以了
      let checkes = this.state.checkes
      checkes[target.dataset.index].value = target.checked
      return checkes
    }
    // 除了checkbox特殊点外,其他的都可以直接用下面的
    this.setState({
      // ES6 计算属性名称语法
      [target.name]: target.name === 'checkes' ?
        setCheckes(target)
        : target.value
    })
}

render() {
  let { username, password, select, radio, textarea, checkes } = this.state;
  return <form>
    <input value={username} onChange={this.handleChange} placeholder="用户名" name='username' type="text"/> <br/>

    <input value={password} name='password' onChange={this.handleChange} placeholder="密码" type="password"/> <br/>

    <button type="button">登陆</button> <br/>

    <select value={select} onChange={this.handleChange} name="select">
      <option value="保姆">保姆</option>
      <option value="老师">老师</option>
    </select>

    <label><input type='radio' name='radio' value='1'
        checked={radio === '1'} onChange={this.handleChange} /> 成功</label><br />
    <label><input type='radio' name='radio'
        value='2' checked={radio === '2'} onChange={this.handleChange} /> 失败</label>

    <textarea name="textarea" value={textarea} onChange={this.handleChange} cols="30" rows="10"></textarea>


    {
        checkes.map((item, index) => {
          return <label key={index}>
            <input type="checkbox"
              data-index={index}
              onChange={this.handleChange}
              name="checkes"
              value={
                // 需要注意,value里无论怎么写,获取的时候都是字符串
                // 其实这里传index就好了,这里的value属性赋予这个itme.value没有意义,因为用不到
                // 这样写的原因是因为我想记录一下自定义属性的写法 data-* 获取用dataset
                item.value

              } checked={item.value} />
            {item.label}
          </label>
        })
      }

      <br/>
  </form>
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

如上例子所写,当一个元素的输入值被 state 绑定,输入动作被 onChange 控制,那么这个组件就是受 react 控制的组件,即受控组件。

我知道,你会可能会觉得这样写太难受了,所以建议你使用 formikopen in new window,这是一个基于 react 封装好的 form 插件,帮我们省去了很多代码的书写

非受控组件

所谓非受控就是将真实数据储存在 DOM 节点中,想要获取数据,就需要先获取元素,在 react 中获取元素可以使用原生 js,或者 ref。

在 react 里最典型的非受控组件是:<input type="file"/> 上传文件组件,由于它的 value 是只读的,我们不能对其进行控制,所以它是一个标准的非受控组件。

非受控组件的行为由有户触发,浏览器执行,react 不对其行为做控制,数据存在 dom 节点中。

Last Updated:
Contributors: websong