不可控组件:<input type="text" defaultValue="HelloWorld"/>数据写死。
可控组件:<input type="text" defaultValue={this.state.value}/>
为什么组件要可控:
符合React的数据流
数据存储在state中,便于使用
便于对数据进行处理
不可控组件代码:
<!DOCTYPE html> <html lang="zh-cn"> <head> <Meta charset="UTF-8"> <title>表单详解</title> </head> <body> <script src="./build/react.js"></script> <script src="./build/JSXTransformer.js"></script> <script type="text/jsx"> /*var MyForm = React.createClass({ render:function () { return <input type="text" defaultValue="HelloWorld!"/> } });*/ var MyForm = React.createClass({ submitHandler:function (event) { event.preventDefault(); var HelloTo = React.findDOMNode(this.refs.helloTo).value;alert(HelloTo); },render:function () { return <form onSubmit={this.submitHandler}> <input type="text" ref="helloTo" defaultValue="Hello World"/><br/> <button type="submit">Speak</button> </form> } }); React.render(<MyForm></MyForm>,document.body ); </script> </body> </html>
可控组件代码:
<!DOCTYPE html> <html lang="zh-cn"> <head> <Meta charset="UTF-8"> <title>表单详解</title> </head> <body> <script src="./build/react.js"></script> <script src="./build/JSXTransformer.js"></script> <script type="text/jsx"> var MyForm = React.createClass({ getInitialState:function () { return{ helloTo:"helloworld" }; },handleChange:function () { this.setState({ helloTo:event.target.value }); },submitHandler:function (event) { event.preventDefault(); alert(this.state.helloTo); },render:function () { return <form onSubmit={this.submitHandler}> <input type="text" value={this.state.helloTo} onChange={this.handleChange}/><br/> <button type="submit">Speak</button> </form> } }); React.render(<MyForm></MyForm>,document.body ); </script> </body> </html>
二、不同表单元素的使用
<label htmlFor="name">Name</label>
<input type="checkBox" value="A" checked={this.state.checked} onChange={this.handleChange}/>
<textarea value={this.state.helloTo} onChange={this.handleChange}/>
<select value={this.state.helloTo} onChange={this.handleChange}> <option value="one">1</option></select>
实例代码如下:
<!DOCTYPE html> <html lang="zh-cn"> <head> <Meta charset="UTF-8"> <title>表单详解</title> </head> <body> <script src="./build/react.js"></script> <script src="./build/JSXTransformer.js"></script> <script type="text/jsx"> var MyForm = React.createClass({ getInitialState:function () { return{ username:"",gender:"man",checked:true }; },handleUsernameChange:function () { this.setState({ username:event.target.value }); },handleGenderChange:function (event) { this.setState({ gender:event.target.value }); },handleCheckBoxChange:function (event) { this.setState({ checked:event.target.checked }); },submitHandler:function () { event.preventDefault(); console.log(this.state); },render:function () { return <form onSubmit={this.submitHandler}> <label htmlFor="username">请输入用户名:</label> <input id="username" type="text" value={this.state.username} onChange={this.handleUsernameChange}/><br/> <select value={this.state.gender} onChange={this.handleGenderChange}><option value="man">男</option> <option value="woman">女</option></select> <br/> <label htmlFor="checkBox">同意用户协议:</label> <input id="checkBox" type="checkBox" value="agree" checked={this.state.checked} onChange={this.handleCheckBoxChange}/> <button type="submit">注册</button> </form> } }); React.render(<MyForm></MyForm>,document.body ); </script> </body> </html>
三、事件处理函数复用
onChange={this.handleChange1}
onChange={this.handleChange2}
onChange={this.handleChange3}
onChange={this.handleChange4}
...
最好的处理方式是:处理成一个onChange={this.handleChange}
(1)bind复用
handleChange:function(name,event){
...
}
{this.handleChange.bind(this,'input1')}
实例代码如下:
handleChange:function (name,event) { var newState = {}; newState[name] = name == "checked"?event.target.checked:event.target.value; this.setState(newState); },submitHandler:function (event) { event.preventDefault(); console.log(this.state); },render:function () { return <form onSubmit={this.submitHandler}> <label htmlFor="username">请输入用户名:</label> <input id="username" type="text" value={this.state.username} onChange={this.handleChange.bind(this,"username")}/><br/> <select value={this.state.gender} onChange={this.handleGenderChange}><option value="man">男</option> <option value="woman">女</option></select> <br/> <label htmlFor="checkBox">同意用户协议:</label> <input id="checkBox" type="checkBox" value="agree" checked={this.state.checked} onChange={this.handleChange.bind(this,"checkBox")}/> <button type="submit">注册</button> </form> } }); React.render(<MyForm></MyForm>,document.body ); </script> </body> </html>
(2)name复用
handleChange:function (event) { var newState = {}; newState[event.target.name] = event.target.name == "checked"?event.target.checked:event.target.value; this.setState(newState); },submitHandler:function (event) { event.preventDefault(); console.log(this.state); },render:function () { return <form onSubmit={this.submitHandler}> <label htmlFor="username">请输入用户名:</label> <input name="username" id="username" type="text" value={this.state.username} onChange={this.handleChange}/><br/> <select name="gender" value={this.state.gender} onChange={this.handleGenderChange}><option value="man">男</option> <option value="woman">女</option></select> <br/> <label htmlFor="checkBox">同意用户协议:</label> <input name="checked" id="checkBox" type="checkBox" value="agree" checked={this.state.checked} onChange={this.handleChange}/> <button type="submit">注册</button> </form> } }); React.render(<MyForm></MyForm>,document.body ); </script> </body> </html>
四、表单组件自定义
为什么要自定义表单组件:
内因:本身具有特殊性:样式统一、信息内聚、行为固定
外因:本质上是组件嵌套
不可控的自定义组件:
代码如下:
<!DOCTYPE html> <html lang="zh-cn"> <head> <Meta charset="UTF-8"> <title>表单详解</title> </head> <body> <script src="./react-0.13.2/react-0.13.2/build/react-with-addons.js"></script> <script src="./react-0.13.2/react-0.13.2/build/JSXTransformer.js"></script> <script type="text/jsx"> var Radio = React.createClass({ getInitialState: function () { return { value: this.props.defaultValue }; },handleChange: function (event) { if (this.props.onChange) { this.props.onChange(event); } this.setState({ value: event.target.value }); },render: function () { var children = {}; var value = this.props.value || this.state.value; React.Children.forEach(this.props.children,function (child,i) { var label = <label> <input type="radio" name={this.props.name} value={child.props.value} checked={child.props.value == value} onChange={this.handleChange} /> {child.props.children} <br/> </label>; children['label' + i] = label; }.bind(this)); return <span>{children}</span>; } }); var MyForm = React.createClass({ submitHandler: function (event) { event.preventDefault(); alert(this.refs.radio.state.value); },render: function () { return <form onSubmit={this.submitHandler}> <Radio ref="radio" name="my_radio" defaultValue="B"> <option value="A">First Option</option> <option value="B">Second Option</option> <option value="C">Third Option</option> </Radio> <button type="submit">Speak</button> </form>; } }); React.render(<MyForm></MyForm>,document.body); </script> </body> </html>
可控组件,示例代码如下:
handleChange: function (event) { if (this.props.onChange) { this.props.onChange(event); } this.setState({ value: event.target.value }); },i) { var label = <label> <input type="radio" name={this.props.name} value={child.props.value} checked={child.props.value == value} onChange={this.handleChange} /> {child.props.children} <br/> </label>; children['label' + i] = label; }.bind(this)); return <span>{children}</span>; } }); var MyForm = React.createClass({ getInitialState: function () { return {my_radio: "B"}; },handleChange: function (event) { this.setState({ my_radio: event.target.value }); },submitHandler: function (event) { event.preventDefault(); alert(this.state.my_radio); },render: function () { return <form onSubmit={this.submitHandler}> <Radio name="my_radio" value={this.state.my_radio} onChange={this.handleChange}> <option value="A">First Option</option> <option value="B">Second Option</option> <option value="C">Third Option</option> </Radio> <button type="submit">Speak</button> </form>; } }); React.render(<MyForm></MyForm>,document.body); </script> </body> </html>