本文实例讲述了react学习之受控组件与数据共享。分享给大家供大家参考,具体如下:
在html当中,像<input>,<textarea>, 和 <select>这类表单元素会自己储存值,并且根据用户输入进行更新。但在react中,可变的值通常保存在组件的state中,并且只能用 setstate() 方法进行更新。为了解决二者的矛盾,可以让html元素不再自己储存数据,而使用来自于react的state。也就是说html元素把数据保存在react组件的state中,并根据state值来渲染更新html的内容。这种值由react控制的表单元素称为受控组件。
1、input
例如将input输入的名字保存在state.name中,并且设置input显示的value值为state.name。当input中输入变化时,onchange触发updatename函数更新name值,从而使input中显示的value发生变化。当点击提交按钮时onclick触发submit()方法来阻止默认的提交,并打印提示信息:
class controlledform extends react.component{
constructor(props){
super(props);
this.state={
name:''
};
this.updatename=this.updatename.bind(this);
this.submit=this.submit.bind(this);
}
updatename(e){ //在调用函数时会默认传入时间参数e
this.setstate({
name:e.target.value //更新name的值为input中输入的值
})
}
submit(e){ //自己定义点击submit后的操作
console.log("姓名"+this.state.name+"提交成功");
e.preventdefault(); //阻止表单默认提交行为
}
render(){
return (
<form onsubmit={this.submitform}>
<label>
姓名:
<input type="text" value={this.state.name} onchange={this.updatename} />
</label>
<input type="submit" value="提交" onclick={this.submit} />
</form>
)
}
}
使用受控组件使得页面的数据都处于react的控制之下,而且可以对其数据进行处理之后再渲染到页面上。
2、textarea
在react中使用<textarea>:为了对textarea的输入内容进行控制,react中的textarea像input一样由value来控制其显示的值,并且通过e.target.value将textarea中的值存入state中。textarea的使用也由闭合式标签<textarea></textarea>变为开放式标签:
<textarea value={this.state.text} onchange={this.updatetext} />
3、select
同理,在react中的<select>也通过value来控制哪个option的选中,并通过e.target.value将选中的option的值传给state。例如和this.state.sex值相同的option会被显示选中
<select value={this.state.sex} onchange={this.updatesex}>
<option value="male">男</option>
<option value="female">女</option>
</select>
4、利用name处理多个受控组件
如上,我们需要为每个受控组件都设置更新方法onchange,而且每个组件的更新方法都很类似,这样看起来很麻烦,我们可以根据name属性区分不同的组件所对应的state值,利用一个函数来实现多个组件state值的更新:
<select value={this.state.sex} name="sex" onchange={this.updateform}>
updateform(e){
let name=e.target.name; //获取组件的name
let value=e.target.value; //获取组件的值value
this.setstate({
[name]:value //为不同name的组件设置value
})
}
在setstate方法中,通过es6的语法计算属性[],在中括号中指定要更新的属性名的表达式来更新不同的state。例如当select调用updateform()时,name="sex",value="male",则通过setstate将state.sex值设为male。
5、组件间数据共享
当两个组件要同时使用一个变量时,由于state只能被它所定义的组件修改、访问,因此不能把state赋给某个组件,而应该将state提升至两个组件最近的公共父组件,父组件再通过props将值传递给子组件,这样两个子组件就都可以访问了。那么子组件怎么去修改父组件的state呢?子组件通过props属性来调用父组件的方法从而修改父组件的state,这样两个组件就通过父组件实现了对state的共享。例如父组件parent的一个子组件childinput负责接收用户的输入,保存在state.text中,在另一个子组件childshow中显示用户的输入:
class parent extends react.component{
constructor(props){
super(props);
this.state={
text:''
};
this.updatetext=this.updatetext.bind(this);
}
updatetext(value){
this.setstate({
text:value
})
}
render(){
return (
<fieldset>
<legend>提升state</legend> //父组件updateinput属性指向updatetext方法
<childinput text={this.state.text} updateinput={this.updatetext}/>
<childshow text={this.state.text} />
</fieldset>
)
}
}
class childinput extends react.component{
constructor(props){
super(props);
this.handlechange=this.handlechange.bind(this);
}
handlechange(e){ //在子组件的方法中调用父组件的updateinput更新text的值
this.props.updateinput(e.target.value);
}
render(){
return (
<div>
<label>
请输入:
<input type="text" value={this.props.text} onchange={this.handlechange}/>
</label>
</div>
)
}
}
class childshow extends react.component{
constructor(props){
super(props); //通过调用父组件构造方法将父组件的props传递给子组件
}
render(){
return (
<div>
<p>输入为:{this.props.text}</p>
</div>
)
}
}
reactdom.render(
<parent/>,
document.getelementbyid('app')
)
运行结果如图:
上例在react中的数据流动如下:
1、当在input中中输入内容时,input内容改变onchange触发childinput组件的handlechange方法,该方法通过this.props调用父组件updateinput方法并传递输入的内容e.target.value。
2、父组件parent在引用子组件childinput时为其定义updateinput属性为this.updatetext方法,因此触发updatetext方法,在该方法中接收子组件传递的参数value,并通过setstate方法修改state.text的值。
3、当state.text值发生改变时,父组件parent通过属性props将值传递给子组件childinput与childshow,引起子组件属性改变,从而子组件重新渲染页面内容。
希望本文所述对大家react程序设计有所帮助。