通常我们的React组件都会有自己的state数据,但是这和我们的JavaScript的表单元素的数据是不相同的。
那我们要如何让JavaScript中的数据和我们React里的state数据保持一致呢?这就需要我们的React的受控组件了.
那什么是受控组件呢?
受控组件
在 HTML 中,表单元素(如<input>
、 <textarea>
和 <select>
)之类的表单元素通常自己维护 state,并根据用户输入进行更新。而在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState()
来更新。
我们可以把两者结合起来,使 React 的 state 成为“唯一数据源”。渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。
textarea 标签
在 React 中, 使用 value 属性代替原本的值。我们可以把state传入。
class EssayForm extends React.Component {
constructor(props) {
super(props);
this.state = {
//初始化默认值为“请输入你的个人介绍”
value: '请输入你的个人介绍.'
};
//绑定我们的this
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
//在框内填入值时执行
handleChange(event) {
this.setState({value: event.target.value});
}
//提交时执行
handleSubmit(event) {
alert('提交: ' + this.state.value);
//阻止事件的默认行为
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
文章:
<textarea value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="提交" />
</form>
);
}
}
select 标签
class FlavorForm extends React.Component {
constructor(props) {
super(props);
//初始化默认值为coconut
this.state = {value: 'coconut'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('你喜欢的风味是: ' + this.state.value);
//阻止事件的默认行为
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
选择你喜欢的风味:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">葡萄柚</option>
<option value="lime">酸橙</option>
<option value="coconut">椰子</option>
<option value="mango">芒果</option>
</select>
</label>
<input type="submit" value="提交" />
</form>
);
}
}
注意
你可以将数组传递到 value 属性中,以支持在 select 标签中选择多个选项:
<select multiple={true} value={['B', 'C']}>
文件 input 标签
在 HTML 中,<input type="file">
允许用户从存储设备中选择一个或多个文件,将其上传到服务器,或通过使用 JavaScript 的 File API进行控制。
<input type="file" />
因为它的 value 只读,所以它是 React 中的一个非受控组件。
处理多个输入
当需要处理多个 input 元素时,我们可以给每个元素添加 name 属性,并让处理函数根据 event.target.name 的值选择要执行的操作。
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
//修改值
handleInputChange(event) {
const target = event.target;
//根据我们的name的值来判断当前是哪个输入框,已经应该修改哪个值
const value = target.name === 'isGoing' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
参与:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<br />
<label>
来宾人数:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}