React表单
受控组件
- 标签 input、textarea、select的值的改变通常是根据用户输入进行更新。在React中,可变状态通常保存在组件的状态属性中,并且只能使用 setState() 更新,而呈现表单的React组件也控制着在后续用户输入时该表单中发生的情况,以这种由React控制的输入表单元素而改变其值的方式,称为:“受控组件”。
不受控组件
- 在受控组件中,表单数据由 React 组件负责处理。另外一个选择是不受控组件,其表单数据由 DOM 元素本身处理。。
处理多个输入元素
- 当您需要处理多个受控的 input 元素时,您可以为每个元素添加一个 name 属性,并且让处理函数根据 event.target.name 的值来选择要做什么。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.item{
margin:10px;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
</html>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
selections: 'strawberry',
sex: '0',
hobby: [
{
'title': "睡觉",
'checked': false,
},
{
'title': "吃饭",
'checked': false
},
{
'title': "敲代码",
'checked': false
}
],
avatar:null,
avatarCDN:'',
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
// 使用 ref 来从 DOM 节点中获取表单数据。
// this.files = React.createRef()
}
// 批量修改受控组件的值
handleChange(event) {
const target = event.target
const name = target.name
// setState() 自动将部分状态合并到当前状态
this.setState({
[name]: target.value
})
}
changeHobby(key) {
var hobby = this.state.hobby
hobby[key].checked = !hobby[key].checked
this.setState({
hobby:hobby
})
}
handleSubmit(event) {
event.preventDefault();
console.log(this.state)
// 获取上传文件的内容
// console.log(this.files.current.files)
}
avatar = (e) =>
{
var avatar = e.target.files[0]
var avatarCDN = URL.createObjectURL(avatar)
this.setState({
avatar:avatar,
avatarCDN:avatarCDN
})
}
render() {
let preview = ''
if(this.state.avatarCDN)
{
preview = <img src={this.state.avatarCDN} />
}
return (
<div>
<form onSubmit={this.handleSubmit}>
<div style={{ margin: '10px' }}>
<label>
名字:
<input type="text" name="username" value={this.state.username} onChange={this.handleChange} />
</label>
</div>
<div style={{ margin: '10px' }}>
<label>
密码:
<input type="password" name="password" value={this.state.password} onChange={this.handleChange} />
</label>
</div>
<div style={{ margin: '10px' }}>
<label>
选择你喜欢的水果:
<select name="selections" value={this.state.selections} onChange={this.handleChange}>
<option value="grapefruit">葡萄柚</option>
<option value="lime">橙子</option>
<option value="strawberry">草莓</option>
<option value="banana">香蕉</option>
<option value="mango">芒果</option>
</select>
</label>
</div>
<div style={{ margin: '10px' }}>
<label>
文件:
{/* <input type="file" ref={this.files} multiple="multiple" /> */}
<input type="file" name="avatar" onChange={this.avatar} /><br />
{preview}<br />
</label>
</div>
<div style={{ margin: '10px' }}>
<label>
性别:
<input type="radio" name="sex" value="0" checked={this.state.sex == '0'} onChange={this.handleChange} /> 保密
<input type="radio" name="sex" value="1" checked={this.state.sex == '1'} onChange={this.handleChange} /> 男
<input type="radio" name="sex" value="2" checked={this.state.sex == '2'} onChange={this.handleChange} /> 女
</label>
</div>
<div style={{ margin: '10px' }}>
<label>
爱好:
{
this.state.hobby.map((item, index) => {
return (
<span key={index}>
<input type="checkbox" checked={item.checked} onChange={this.changeHobby.bind(this, index)} />
{item.title}
</span>
)
})
}
</label>
</div>
<div style={{ margin: '10px' }}>
<input type="submit" value="提交" />
</div>
</form>
</div>
)
}
}
var vm = ReactDOM.render(
<NameForm />,
document.getElementById("root")
);
</script>