九、react表单处理

一、说明

下面代码运行后会报错,因为在React中并不存在类似于Vue的双向数据绑定操作

 1 import React, { Component } from "react";
 2 
 3 class App extends Component {
 4   state = {
 5     msg: "hello world",
 6   };
 7   render() {
 8     return (
 9       <div>
10         <input type="text" value={this.state.msg} />
11       </div>
12     );
13   }
14 }
15 
16 export default App;

需要注意以下几点

1、Vue中的v-model是语法糖

2、React里使用的是单向数据流

二、受控组件

state与表单项中的value值绑定在一起,由state的值来控制表单元素的值,称为受控组件

绑定步骤

1、添加一个state状态,作为表单元素的value值

2、给表单元素绑定change事件,将表单元素的值设置为state的值

 1 // 案例一:
 2 import React from 'react'
 3 class Login extends React.Component{
 4   
 5   state = {
 6     username: '',
 7     password: ''
 8   }
 9 
10     // 保存用户名到状态中
11   saveUsername = (event) => {
12     this.setState(state => {
13       return {
14         username: event.target.value
15       }
16     })
17   }
18   // 保存用户密码到状态中
19   savePassword = (event) => {
20     this.setState(state => {
21       return {
22         password: event.target.value
23       }
24     })
25   }
26   // 表单提交的回调
27   handleSubmit = (event) => {
28     event.preventDefault()
29     const {username, password} = this.state
30     //console.log(username, password)
31   }
32   
33   render(){
34     return(
35       <form
36         action="https://www.baidu.com"
37         onSubmit={handleSubmit}>
38           用户名:<input
39               onChange={saveUsername}
40               type="text"
41               name="usename"/>
42         密码:<input
43              onChange={savePassword}
44              type="text"
45              name="password"/>
46         <button>登录</button>
47       </form>
48     )
49   }
50 }
51 export default Login;
 1 // 案例二:受控组件,用户信息修改
 2 import React, { Component } from "react";
 3 
 4 class App extends Component {
 5   state = {
 6     userinfo: {
 7       username: "zhangsan",
 8       mobile: "13800138000",
 9       email: "zhangsan@hahaha.com",
10       gender: "女",
11       edm: true,
12     },
13   };
14   render() {
15     // 获取初始的数据
16     let { username, mobile, email, gender, edm } = this.state.userinfo;
17     return (
18       <div>
19         <div>
20           <input
21             type="text"
22             value={username}
23             name="username"
24             onChange={this.changeHandler.bind(this)}/>
25         </div>
26         <div>
27           <input
28             type="text"
29             value={mobile}
30             name="mobile"
31             onChange={this.changeHandler.bind(this)}/>
32         </div>
33         <div>
34           <input
35             type="text"
36             value={email}
37             name="email"
38             onChange={this.changeHandler.bind(this)}/>
39         </div>
40         <div>
41           <input
42             type="radio"
43             value="男"
44             name="gender"
45             checked={gender === "男" ? true : false}
46             onChange={this.changeHandler.bind(this)}/>
47 48           <input
49             type="radio"
50             value="女"
51             name="gender"
52             checked={gender === "女" ? true : false}
53             onChange={this.changeHandler.bind(this)}/>
54 55         </div>
56         <div>
57           <input
58             type="checkbox"
59             name="edm"
60             checked={edm ? true : false}
61             onChange={this.changeHandler.bind(this)}/>
62           接受电子邮件营销
63         </div>
64         <div>
65           <button onClick={this.submitForm.bind(this)}>提交</button>
66         </div>
67       </div>
68     );
69   }
70   changeHandler(e) {
71     // console.log(e.target.value);
72     let value = e.target.value;
73     let name = e.target.name;
74     let type = e.target.type;
75     this.setState((state) => {
76       if (type === "checkbox") {
77         state.userinfo[name] = !state.userinfo[name];
78         // if(state.userinfo[name]){
79         //     state.userinfo[name] = false;
80         // }else{
81         //     state.userinfo[name] = true;
82         // }
83       } else {
84         state.userinfo[name] = value;
85       }
86       return state;
87     });
88   }
89   submitForm(){
90     // 表单提交时收集表单数据
91     console.log(this.state.userinfo);
92   }
93 }
94 export default App;
  • 如果需要将原本应该分别处理的事件合在一起去写的话,一定需要多传递一个参数用于记录当前修改的是state中的哪一个值,此时可以选择以下方案中的任意一种:
    • 通过相同name属性值去辨别,给每个表单项设置与state中相同的key名的name值,然后通过事件对象去获取
    • 可以直接在事件绑定的位置传递标记,例如:onChange={this.changeHandler.bind(this,'username')}
  • 表单项中表单项类型为checkbox的比较特殊,与其他类型的不同,需要特殊处理(取反操作,而其余的表单项是来什么值用什么值)

三、非受控组件

现用现取,没有和state数据源进行关联的表单项

借助ref,使用元素DOM方式获取表单元素值

 

 1 // 案例一:回调形式的ref
 2 import React from 'react'
 3 class Login extends React.Component{
 4   
 5   handleSubmit = (event) => {
 6     event.preventDefault()
 7     const {username, password} = this
 8     console.log(username, password)
 9   }
10   
11   render(){
12     return(
13       <form
14         action="https://www.baidu.com"
15         onSubmit={handleSubmit}>
16           用户名:<input
17               ref={c => this.username = c}
18               type="text"
19               name="usename"/>
20         密码:<input
21              ref={c => this.password = c}
22              type="text"
23              name="password"/>
24         <button>登录</button>
25       </form>
26     )
27   }
28 }
29 export default Login
  • 使用步骤
    • 调用React.createRef()方法创建ref对象
    • 将创建好的ref对象添加到文本框中
    • 通过ref对象获取到文本框的值

一般表单项少的时候可以考虑使用非受控组件。

非受控组件不能给表单项加value属性,一旦加了它就不是非受控组件了,它就成了受控组件了。如果有默认值通过defaultValue属性进行输出。

 1 // 案例二:createRef()形式
 2 import React, { Component, createRef } from "react";
 3 
 4 class App extends Component {
 5   constructor(props) {
 6     super(props)
 7     this.username = createRef()
 8   }
 9   render() {
10     return (
11       <div>
12         <div>
13           <input type="text" defaultValue="" ref={this.username} />
14         </div>
15         <div>
16           <button onClick={this.submitForm.bind(this)}>提交</button>
17         </div>
18       </div>
19     );
20   }
21   submitForm() {
22     console.log(this.username.current.value);
23   }
24 }
25 
26 export default App;

 

posted @ 2021-07-12 13:02  大米饭盖饭  阅读(137)  评论(0)    收藏  举报