React(九)—— 操作表单
2019-02-25 本文已影响17人
感觉不错哦
React的表单应用是有一些小坑的,练习的时候也是遇到了很多,希望这边能帮助到大家
在写表单之前写一个基础方法,bind函数
function list(){
console.log(arguments[0])
return Array.prototype.slice.call(arguments)
}
var lists=list.bind(null,4) //bind 函数后续参数等于=预设参 并且在实参最前面,可传多个用逗号隔开
console.log(lists(1,2,3)) //打印4 ,[4,1,2,3]
常常我们只理解了第一个参数,第二个参数可能有点陌生
开始React表单处理
<script type="text/babel">
class FormComponent extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<div>
<form>
</form>
</div>
)
}
}
ReactDOM.render(<FormComponent/>,document.getElementById('div'))
</script>
老规矩 初始化!!每次都手打一遍
首先编辑几个默认初始状态
constructor(props){
super(props)
this.state={
username:'',
checked:true,
gender:'man'
}
}
待会将以上的默认状态绑定给input
render(){
return(
<div>
<form>
<label htmlFor="username">请输入您的姓名:</label>
<input name="username" />
<br/>
</form>
</div>
)
}
简单写个单标签input,注意一点就是for,基于jsx的小驼峰写法,这里的for要写成htmlFor,接下来再写两个状态
render(){
return(
<div>
<form>
<label htmlFor="username">请输入您的姓名:</label>
<input name="username" />
<br/>
<label htmlFor="checked">Yes or No</label>
<input name="checked" type="checkbox" />
<br/>
<label htmlFor="gender">帅哥 or 美铝</label>
<select name="gender">
<option value="man">Cool Man</option>
<option value="woman">Sure Woman</option>
</select>
<br/>
</form>
</div>
)
}
简单编写常用的几个常用的表单元素
给它加一下默认值
render(){
return(
<div>
<form>
<label htmlFor="username">请输入您的姓名:</label>
<input name="username" value={this.state.username} />
<br/>
<label htmlFor="checked">Yes or No</label>
<input name="checked" type="checkbox" checked={this.state.checked} />
<br/>
<label htmlFor="gender">帅哥 or 美铝</label>
<select name="gender" value={this.state.gender}>
<option value="man">Cool Man</option>
<option value="woman">Sure Woman</option>
</select>
<br/>
</form>
</div>
)
}
因为React是单向数据流,它不像vue是双向绑定的,相当于我此时已经把表单的值写死了,在React表单中统一使用onChange监听值的改变
<script type="text/babel">
class FormComponent extends React.Component{
constructor(props){
super(props)
this.state={
username:'',
checked:true,
gender:'man'
}
}
handleChangeUsername(event){
this.setState({username:event.target.value})
}
handleChangeChecked(event){
this.setState({checked:!this.state.checked})
}
handleChangeGender(event){
this.setState({gender:event.target.value})
}
render(){
return(
<div>
<form>
<label htmlFor="username">请输入您的姓名:</label>
<input name="username" value={this.state.username} onChange={this.handleChangeUsername.bind(this)} />
<br/>
<label htmlFor="checked">Yes or No</label>
<input name="checked" type="checkbox" checked={this.state.checked} onChange={this.handleChangeChecked.bind(this)} />
<br/>
<label htmlFor="gender">帅哥 or 美铝</label>
<select value={this.state.gender} onChange={this.handleChangeGender.bind(this)}>
<option value="man">Cool Man</option>
<option value="woman">Sure Woman</option>
</select>
<br/>
</form>
</div>
)
}
}
ReactDOM.render(<FormComponent/>,document.getElementById('div'))
</script>
此时的逻辑就是在React更改值的时候先修改默认的state,再渲染到对应的数据,当然这么写是不好的,代码量重复太多,此时就可以使用bind复用的方法
render(){
return(
<div>
<form>
<label htmlFor="username">请输入您的姓名:</label>
<input name="username" value={this.state.username} onChange={this.handleChange.bind(this,'username')} />
<br/>
<label htmlFor="checked">Yes or No</label>
<input name="checked" type="checkbox" checked={this.state.checked} onChange={this.handleChange.bind(this,'checked')} />
<br/>
<label htmlFor="gender">帅哥 or 美铝</label>
<select value={this.state.gender} onChange={this.handleChange.bind(this,'gender')}>
<option value="man">Cool Man</option>
<option value="woman">Sure Woman</option>
</select>
<br/>
</form>
</div>
)
}
首先针对开篇提到的bind方法,将标签的name作为函数参数传递,并且方法名都是相同的,那bind传递的参数即是函数的第一个参数
handleChange(name,event){
var newState={}
naeState[name]
}
在方法中新建一个对象,利用关联数组的写法针对起初状态的key值建立对应的value
handleChange(name,event){
var newState={}
newState[name]=name=="checked"?event.target.checked:event.target.value
this.setState(newState)
}
首先参数name就是对应事件的对象,中间那句代码乍一看有点迷,其实是很简单的三元运算符,如果当前改变的对象不是checkbox就传入改变的value,不理解多看几遍,类似函数重载的思想,放一下代码,真实代码以下方代码为准,可能有误差,加了一个提交的小事件
<script type="text/babel">
class FormComponent extends React.Component{
constructor(props){
super(props)
this.state={
username:'',
checked:true,
gender:'man'
}
}
handleChange(name,event){
var newState={}
newState[name]=name=="checked"?event.target.checked:event.target.value
this.setState(newState)
}
handleSubmit(event){
event.preventDefault();
var is=this.state.checked?'是':'不是'
var gender=this.state.gender=='man'?'帅哥':'美女'
alert(this.state.username+is+gender)
}
render(){
return(
<div>
<form>
<label htmlFor="username">请输入您的姓名:</label>
<input name="username" value={this.state.username} onChange={this.handleChange.bind(this,'username')} />
<br/>
<label htmlFor="checked">Yes or No</label>
<input name="checked" type="checkbox" checked={this.state.checked} onChange={this.handleChange.bind(this,'checked')} />
<br/>
<label htmlFor="gender">帅哥 or 美铝</label>
<select name="gender" value={this.state.gender} onChange={this.handleChange.bind(this,'gender')}>
<option value="man">Cool Man</option>
<option value="woman">Sure Woman</option>
</select>
<br/>
<button type="submit" onClick={this.handleSubmit.bind(this)}>提交</button>
</form>
</div>
)
}
}
ReactDOM.render(<FormComponent/>,document.getElementById('div'))
</script>
可能有些小伙伴觉得还是有点烦,写这些name,name也是可以获取的
首先取消参数的传递,然后在方法中获取name
handleChange(event){
var newState={}
newState[event.target.name]=event.target.name=="checked"?event.target.checked:event.target.value
this.setState(newState)
}
需要注意的点就是,React是单向流,如果我们在表单中不设置onChange事件是没法重新渲染的
...这边补充一个真实DOM写法,当然是不建议使用的
<script type="text/babel">
class FormComponent extends React.Component{
constructor(props){
super(props)
}
handleChange(){
var inputValue=ReactDOM.findDOMNode(this.refs.test).value;
console.log(inputValue)
}
render(){
return (
<div>
<form>
<input ref="test" onChange={this.handleChange.bind(this)} />
</form>
</div>
)
}
}
ReactDOM.render(<FormComponent/>,document.getElementById('div'))
</script>
这里有个坑就是如果给input添加value值是没办法重新改变的,设置defaultValue即可