您好,登錄后才能下訂單哦!
表單組件兩種類型:約束組件和無約束組件
1. 無約束組件:
eg:
var MyForm = React.createClass({
render: function() {
return <input type="text" defaultValue="Hello World!"/>;
}
});
組件的value并非由父組件設置,而是讓<input/>自己控制自己的值。
一個無約束的組件沒有太大用處,除非可以訪問它的值??梢酝ㄟ^給<input/>添加一個ref屬性以訪問到DOM節(jié)點的值。ref是一個不屬于DOM屬性的特殊屬性??梢酝ㄟ^this上下文訪問這個節(jié)點,所有的ref都添加到了this.refs上。
eg:調(diào)用value:
var MyForm = React.createClass({
submitHandler: function(event) {
event.preventDefault();
//通過ref訪問輸入框
var helloTo = this.refs.helloTo.getDOMNode().value;
alert(helloTo);
}
render: function() {
return (
<form onSubmit={this.submitHandler}>
<input ref="helloTo" type="text" defaultValue="Hello World!"/>
<br />
<button type="submit">Speak</button>
</form>
);
}
});
2. 約束組件:
約束組件的模式與React其他類型組件的模式一致。表單的狀態(tài)交由React組件控制。狀態(tài)值被存儲在React組件的state中。
約束組件能更好的控制表單組件。在約束組件中,輸入框的值是由父組件社設置的。
eg:
var MyForm = React.createClass({
getInitialState: function() {
return {
helloTo: "Hello World!"
};
}
handleChange: function(event) {
this.setState({
helloTo: event.target.value
});
}
submitHandler: function(event) {
event.preventDefault();
//通過ref訪問輸入框
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>
);
}
});
約束組件可以控制數(shù)據(jù)流,在用戶輸入數(shù)據(jù)時更新state。如將用戶輸入的字符轉(zhuǎn)成變大寫(如:this.setState({helloTo: event.target.value.toUpperCase()});)并添加到輸入框時不會發(fā)生閃爍。這是因為React攔截了瀏覽器原生的change事件,在setState被調(diào)用后,這個組件就會重新渲染輸入框。然后React計算差異,更新輸入框的值。
3. 表單事件:
React支持所有HTML事件。這些事件遵循駝峰命名的約定,且會被轉(zhuǎn)成合成事件。這些事件是標準化的,提供了跨瀏覽器的一致接口。
所有合成事件都提供了event.target來訪問觸發(fā)事件的DOM節(jié)點。
訪問約束組件最簡單的方式之一:
handleEvent: function(syntheticEvent) {
var DOMNode = syntheticEvent.target;
var newValue = DOMNode.value;
}
4. Label:
Label是表單元素中重要組件,可以明確地向用戶傳達你的要求,提升單選框和復選框的可用性。
React中class變成className,for變?yōu)閔tmlFor:
<label className="col-sm-3 control-label no-padding-right">開戶行<span className="red">*</span></label>
5. 文本框和Select:
React中的<textarea/>和<select/>:(約束的)
<textarea value={this.state.value} onChange={this.handleChange} />
<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>
多選時可在select后加上multi={true}屬性
當使用多選的select時,select組件的值不會更新,只有選項的selected屬性會發(fā)生變化??梢允褂胷ef或event.target來訪問選項,檢查它們是否被選中。
eg:
handleChange: function(event) {
var checked = [];
var sel = event.target;
for(var i = 0; i < sel.length; i++) {
var value = sel.value[i];
if (value.selected) {
checked.push(value.value);
}
}
}
6. 復選框和單選框:
類型為checkbox或radio的<input/>與類型為text的<input/>的行為完全不一樣。通常復選框和單選框的值是不變的,只有checked狀態(tài)會變化。所以要控制復選框或單選框就要控制它們的checked屬性。也可以在非約束的復選框或者單選框中使用defaultChecked。
<input type="checkbox" className="ace"
checked={this.state.outboundLogisticsStatus == "SENTED"}
onChange={this.handleLogisticsStatusChange}/>
<span className="lbl">推送出庫單
</span>
7. 表單元素的name屬性:
在React中,name屬性對于表單元素來說并沒有那么重要,因為約束表單組件已經(jīng)把值存儲到了state中,并且表單的提交事件也會被攔截。在獲取表單值的時候,name屬性并不是必須的。對于非約束的表單組件來說,也可以使用refs來直接訪問表單元素。
那么屬性的作用:
-- name屬性可以讓第三方表單序列化類庫在React中正常工作;
-- 對于仍然使用傳統(tǒng)提交方式的表單來說,name屬性是必須的;
-- 在用戶瀏覽器中,name被用在自動填寫常用信息中,比如用戶地址;
-- 對于非約束的單選框組件,name是有必要的,它可以作為這些組件分組的依據(jù),確保在同一時刻,同一個表單中擁有相同name的單選框只有一個可以被選中。如果不使用name屬性,這一行為可以使用約束的單選框?qū)崿F(xiàn)。
8. 多個表單元素與change處理器:
重用事件處理器:
-- 通過.bind傳遞其他參數(shù)
var MyForm = React.createClass({
getInitialState: function () {
return {
given_name: "",
family_name: ""
};
},
handleChange: function (name, event) {
var newState = {};
newState[name] = event.target.value;
this.setState(newState);
},
submitHandler: function (event) {
event.preventDefault();
var words = [
"Hi",
this.state.given_name,
this.state.family_name
];
alert(words.join(" "));
},
render: function () {
return <form onSubmit={this.submitHandler}>
<label htmlFor="given_name">Given Name:</label>
<br />
<input
type="text"
name="given_name"
value={this.state.given_name}
onChange={this.handleChange.bind(this,'given_name')}/>
<br />
<label htmlFor="family_name">Family Name:</label>
<br />
<input
type="text"
name="family_name"
value={this.state.family_name}
onChange={this.handleChange.bind(this,'family_name')}/>
<br />
<button type="submit">Speak</button>
</form>;
}
});
-- 使用DOMNode的name屬性來判斷需要更新哪個組件的狀態(tài)
var MyForm = React.createClass({
getInitialState: function () {
return {
given_name: "",
family_name: ""
};
},
handleChange: function (event) {
var newState = {};
newState[event.target.name] = event.target.value;
this.setState(newState);
},
submitHandler: function (event) {
event.preventDefault();
var words = [
"Hi",
this.state.given_name,
this.state.family_name
];
alert(words.join(" "));
},
render: function () {
return <form onSubmit={this.submitHandler}>
<label htmlFor="given_name">Given Name:</label>
<br />
<input
type="text"
name="given_name"
value={this.state.given_name}
onChange={this.handleChange}/>
<br />
<label htmlFor="family_name">Family Name:</label>
<br />
<input
type="text"
name="family_name"
value={this.state.family_name}
onChange={this.handleChange}/>
<br />
<button type="submit">Speak</button>
</form>;
}
});
-- React.addons.LinkedStateMixmin為組件提供一個linkState方法。linkState返回一個對象,包含value和requestChange兩個屬性。
value根據(jù)提供的name屬性從state中獲取對應的值
requestChange是一個函數(shù),使用新的值更新同名的state
eg:
this.linkState('given_name');
//返回
{
value: this.state.given_name
requestChange: function (newValue) {
this.setState({
given_name: newValue
});
},
}
需要把這個對象傳遞給一個React特有的非DOM屬性valueLink。valueLink使用對象提供的value更新表單域的值,并提供一個onChange處理器,當表單域更新時使用新的值調(diào)用requestChange。
var MyForm = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function () {
return {
given_name: "",
family_name: ""
};
},
submitHandler: function (event) {
event.preventDefault();
var words = [
"Hi",
this.state.given_name,
this.state.family_name
];
alert(words.join(" "));
},
render: function () {
return <form onSubmit={this.submitHandler}>
<label htmlFor="given_name">Given Name:</label>
<br />
<input
type="text"
name="given_name"
valueLink={this.linkState('given_name')} />
<br />
<label htmlFor="family_name">Family Name:</label>
<br />
<input
type="text"
name="family_name"
valueLink={this.linkState('family_name')} />
<br />
<button type="submit">Speak</button>
</form>;
}
});
這種方法便于控制表單域,把其值保存在父組件中的state中。而且,其數(shù)據(jù)流仍然與其他約束的表單元素保持一致。
但是使用這種方式往數(shù)據(jù)流中添加定制功能時,復雜度會增加。建議只在特定的場景下使用。因為傳統(tǒng)約束表單組件提供了同樣的功能且更加靈活。
9. 自定義表單組件:
可以在項目中復用共有功能。也是一種將交互界面提升為一種更加復雜的表單組件(如單選框、多選框)的好方法。
eg:自定義表單單選框和valueLink結(jié)合使用:
<div className="col-sm-10">
<PaymentDistrictSelect valueLink={this.linkState('paymentDistrictCode')}/>
</div>
10. Focus:
控制表單組件的focus可以很好地引導用戶按照表單邏輯逐步填寫??蓽p少用戶操作,增強可用性。
11. 可用性:
React組件常常缺乏可用性。如缺乏對鍵盤操作的支持。
12. 傳達要求:
placeholder可以用來顯示輸入實例或作為沒有輸入時的默認值
<input type="text" name="keyword" placeholder="對賬單號/預付單號" valueLink={this.linkState("keyword")} style={{width: '100%'}}/>
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。