Skip to content
On this page

受控组件 & 非受控组件

受控组件

在 React 中,HTML 表单的处理方式和普通的 DOM 元素不太一样:表单元素通常会保存在一些内部的 state。

  • HTML 中的表单元素是可输入的,也就是有自己的可变状态
  • 而 React 中可变状态通常保存在 state 中,并且只能通过 setState() 方法来修改
  • React 讲 state 与表单元素值 value 绑定在一起,有 state 的值来控制表单元素的值
  • 受控组件:值受到 react 控制的表单元素

input

jsx
class  NameForm extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      username: "BOb"
    }
  }
  onChange (e) {
    console.log(e.target.value);
    this.setState({
      username: e.target.value
    })
  }
  render () {
    return <input name="username" value={this.state.username} onChange={(e) => this.onChange(e)} />
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

select

jsx
class  NameForm extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      username: "BOb"
    }
  }

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

  render () {
    return(
        <select name="fruits"
                onChange={e => this.handleChange(e)}
                value={this.state.fruits}>
            <option value="apple">苹果</option>
            <option value="banana">香蕉</option>
            <option value="orange">橘子</option>
        </select>
    )
  }
}
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

受控组件多个输入

jsx
export default class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      username: "",
      password: "",
      valid: ""
    }
  }

  render() {
    return (
      <div>
        <form onSubmit={e => this.handleSubmit(e)}>
          <label htmlFor="username">
            用户:
            <input type="text"
                   id="username"
                   name="username"
                   onChange={e => this.handleChange(e)}
                   value={this.state.username}/>
          </label>
          <br/>
          <label htmlFor="password">
            密码:
            <input type="text"
                   id="password"
                   name="password"
                   onChange={e => this.handleChange(e)}
                   value={this.state.password}/>
          </label>
          <br/>
          <label htmlFor="valid">
            验证:
            <input type="text"
                   id="valid"
                   name="valid"
                   onChange={e => this.handleChange(e)}
                   value={this.state.valid}/>
          </label>
          <br/>
          <input type="submit" value="提交"/>
        </form>
      </div>
    )
  }

  handleSubmit(event) {
    event.preventDefault();
    const {username, password, valid} = this.state;
    console.log(username, password, valid);
  }

  handleChange(event) {
    this.setState({
      // 计算属性名
      [event.target.name]: event.target.value
    })
  }
}

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
ElementValue propertyChange callbackNew value in the callback
<input type="text"/>value="string"onChangeevent.target.value
<input type="checkbox"/>checked=(boolean)onChangeevent.target.checked
<input type="radio" />checked=(boolean)onChangeevent.target.checked
<textarea/>value="string"onChangeevent.target.value
<select/>value="option value"onChangeevent.target.value

非受控组件

  • 调用 React.createRef() 方法创建 ref 对象
  • 将创建好的 ref 对象添加到文本框中
  • 通过 ref 对象获取到文本框的值
  • 非受控组件: 表单组件没有 value prop 就可以称为非受控组件
jsx
class App extends React.Component {
    constructor(){
        super()

        //创建 ref
        this.txtRef = React.createRef()
    }
    // 获取文本框的值
    getTxt =() => {
        console.log(this.txtRef.current.value)
    }

    render(){
        return (
          <div>
            <input type ="text" ref={this.txtRef} />
            <button onClick ={this.getTxt}>获取值</button>
          </div>
        )
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

在 React 渲染生命周期时,表单元素上的 value 将会覆盖 DOM 节点中的值。因此我们可以用 defaultValue 属性来指定表单元素的默认值。

同样,<input type="checkbox"><input type="radio">支持 defaultChecked,<select><textarea>支持 defaultValue。

沪ICP备20006251号-1