React中,表单元素和其他元素的工作有些差异 ,因为表单元素天生包括一些内置状态。举例来说,这个原生HTML表单接受一个name:
<form><label>Name:<input type="text" name="name" /></label><input type="submit" value="Submit" /></form>
该表单具有原生HTML行为:当用户点击提交,浏览修的页面。你希望React中也有这样的行为也是奏效的。但是更普遍的场景中,使用一个JavaScript函数处理表单提交,并且访问用户在表单中输入的数据是很方便的。标准的方式来完成上述功能使用技术叫“控制组件”(Controlled Component)。
控制组件
HTML中,像,这样的元素,通常维持他们自己的状态并根据用户输入更新。在React中,可变的状态通常在组件的state中体现并且只能由setState()更新。
将React状态变成“真理的唯一源头”,我们就能将这两点结合起来。接着,渲染了表单的React组件也能在用户随之而来的输入中控制着表单。一个由React控制着的输入表单元素在这种方式下就叫“控制组件”。
举例,如果我们想将先前的例子变成点击提交后输出name,我们可以把表单写成像控制组件那样:
class NameForm extends React.Component {constructor(props) {super(props);this.state = {value: ''};this.handleChange = this.handleChange.bind(this);this.handleSubmit = this.handleSubmit.bind(this);}handleChange(event) {this.setState({value: event.target.value});}handleSubmit(event) {alert('A name was submitted: ' + this.state.value);event.preventDefault();}render() {return (<form onSubmit={this.handleSubmit}><label>Name:<input type="text" value={this.state.value} onChange={this.handleChange} /></label><input type="submit" value="Submit" /></form>);}}
既然value属性是我们表单自己设置的,那显示的值永远是this.state.value,反映着‘真理的源头’。由于在每一次键盘输入后都会调用handleChange来更新state状态,显示在界面的数值就会根据用户输入更新。
使用控制组件,每一个可变状态将会关联一个处理函数。这使得它可以直接修改或者验证用户输入。举例来说,假如我们想强行的把name变成大写字母,我们可以再handleChange中这样写:
handleChange(event) {this.setState({value: event.target.value.toUpperCase()});}
标签:textarea
在HTML中,textarea标签通过其子元素定义它的文本。
<textarea>Hello there, this is some text in a text area</textarea>
在React中,textarea标签使用value属性代替。用这样的方式,使用
class EssayForm extends React.Component {constructor(props) {super(props);this.state = {value: 'Please write an essay about your favorite DOM element.'};this.handleChange = this.handleChange.bind(this);this.handleSubmit = this.handleSubmit.bind(this);}handleChange(event) {this.setState({value: event.target.value});}handleSubmit(event) {alert('An essay was submitted: ' + this.state.value);event.preventDefault();}render() {return (<form onSubmit={this.handleSubmit}><label>Name:<textarea value={this.state.value} onChange={this.handleChange} /></label><input type="submit" value="Submit" /></form>);}}
注意我们在构造器中初始化this.state.value,这样textarea一开始就有文字在里面。
标签:select
HTML中, 标签生成下拉表单,举例,下面的HTML生成喜好的列表:
<select><option value="grapefruit">Grapefruit</option><option value="lime">Lime</option><option selected value="coconut">Coconut</option><option value="mango">Mango</option></select>
注意Coconut选项是默认初始选择的,因为设置了selected属性。React中,不用selected属性,用select根标签中的value属性。这样对于控制组件来说更方便因为你只需在一处更新,就像这样:
class FlavorForm extends React.Component {constructor(props) {super(props);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('Your favorite flavor is: ' + this.state.value);event.preventDefault();}render() {return (<form onSubmit={this.handleSubmit}><label>Pick your favorite La Croix flavor:<select value={this.state.value} onChange={this.handleChange}><option value="grapefruit">Grapefruit</option><option value="lime">Lime</option><option value="coconut">Coconut</option><option value="mango">Mango</option></select></label><input type="submit" value="Submit" /></form>);}}
总之,这样, 工作起来就很相似— 他们都接受value属性,通过value可以实现控制组件。
注意: 你也能在value属性中传递一个数组,这样做能实现多选项选中:
