一、不可控组件和可控组件
不可控组件:<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
>
<!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 >
<!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 >
<!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 >
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 >