React表单详解

一、不可控组件和可控组件
不可控组件:<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')}
实例代码如下:
<!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
            };
        },
        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 name = event.target.name
}
{this.handleChange}
实例代码如下:
<!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
            };
        },
        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>


可控组件,示例代码如下:
<!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({
        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>

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值