组件可以按不同角度做分类,这次从表单元素的使用开始。不同于div、span等元素只需根据状态来展示内容,表单元素自身可以维护一些状态,但是默认不受React控制。比如,一个input输入框,会随用户的输入而改变。这样的交互行为明显违背了React的基本原则--状态的改变必须通过组件的state。
受控组件
为了达到由React来控制表单元素的值,可以在用户和表单元素发生交互时控制表单元素的行为,从而保证组件的state成为表单元素状态的唯一来源,也就是表单元素的值是由React来管理。
不同表单元素实现的方式不一样
文本框
文本框包含类型为text的<input>元素和<textarea>元素。通过表单元素的value属性设置表单元素的值,通过onChange事件监听值得变化,并将变化同步到React组件的state中
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {name: ''};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
const target = event.target;
this.setState({[target.name]: target.value});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input name="name" type="text" value={this.state.name} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
下拉列表
<select name="cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="fiat" selected="selected">Fiat</option>
</select>
React与原生使用selcted定义选中项不同,它通过在<selcet>上定义value属性来决定那个<option>元素处于选中项。
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<select name="cars" value={this.state.value} onChange={this.handleChange}>
<option value="volvo">苹果</option>
<option value="saab">香蕉</option>
<option value="fiat">凤梨</option> </select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
复选框和单选框
类型为checkbox和radio的<input>元素,受控方式不同于text类型。React控制的不在是value属性,而是checked属性。
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {
apple: false,
orange: false
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
const target = event.target;
this.setState({[target.name]: target.checked});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Apple
<input name="apple" type="checkbox" vlaue="apple" checked={this.state.apple} onChange={this.handleChange} />
</label>
<label>
orange
<input name="apple" type="checkbox" vlaue="orange" checked={this.state.orange} onChange={this.handleChange} /> </label>
<input type="submit" value="Submit" /> </form>
);
}
}
非受控组件
受控组件需要每个元素绑定onChange事件,比较繁琐。另一种方式就是使用非受控组件,不用React来管理状态,所以需要一种方式来获取到表单元素的值。
ref
React提供了一个特殊的属性ref,用来引用React组件或DOM元素的实例,故可以通过为表单元素定义ref属性来获取元素的值。
handleSubmit(event){
// 通过this.input 获取到input元素的值
alert(“value is" + this.input.vlaue);
event.preventDefault()
}
//this.input 指向当前input元素
<input type="text" ref={(inptu) => this.input = input} />
ref值是个函数,会接受当前元素作为参数,然后把input赋值给了this.input。进而可以在组件的其他地方通过this.input获取这个元素。
defaultValue
因为使用非受控组件,通常需要设置默认值,但是无法再通过value属性设置。所以可以使用defaultValue属性设置默认值。类似的,select和textarea也可以设置defalutValue,<input type="checkbox"> 和<input type="radio">则设置defaultChecked属性设置默认值。