react表單
【小案例】用受控元件和非受控元件兩種方式展示,檢測使用者表單輸入和提交
受控元件
1.構造一個state,建立一條value為空
constructor(props) {
super(props);
this.state ={
value:''
}
}複製程式碼
2.建立form表單元素,內部input輸入框,將使用者輸入的value和state中的value繫結
【注意】此時介面上的input框由於受state初始狀態為空的影響,目前不能輸入
render(){
return(
<form className="p-5" onSubmit={this.handleSubmit}>
<div className="form-group">
<label>留言內容</label>
<input
type="text"
className="form-control"
placeholder="請輸入內容"
onChange={this.handleChange}
value={this.state.value}
/>
</div>
<button type="submit" className="btn btn-primary">留言</button>
</form>
)
}複製程式碼
3.給input表單新增onChange事件檢測使用者改變input輸入框內容
onChange={this.handleChange}複製程式碼
4.定義handleChange表單檢測事件方法,呼叫setState更新state狀態,讓state中的value
為使用者輸入的value,則使用者現在輸入的內容通過修改state可展示在介面上
handleChange(event){
this.setState({
value:event.target.value
})
}複製程式碼
5.給form標籤繫結監測使用者提交事件
onSubmit={this.handleSubmit}複製程式碼
6.定義監測使用者提交事件方法,阻止submit的預設提交事件,
此時使用者點選提交按鈕後,會彈出使用者所輸入的值
handleSubmit(event){
alert(this.state.value)
event.preventDefault()
}複製程式碼
非受控元件
1.建立form表單標籤,input輸入框,和submit提交按鈕
2.給input標籤繫結 ref={(textInput)=>{this.textInput = textInput}} 用來直接獲取dom節點的值,此處將textInput的值賦給this.textInput,讓外部能訪問
3.給form標籤繫結監測使用者提交事件 onSubmit={this.handleSubmit}
render(){
return(
<form className="p-5" onSubmit={this.handleSubmit}>
<div className="form-group">
<label>留言內容</label>
<input
type="text"
className="form-control"
placeholder="請輸入內容"
ref={(textInput)=>{this.textInput = textInput}}
/>
</div>
<button type="submit" className="btn btn-primary">留言</button>
</form>
)
}複製程式碼
4.定義使用者提交事件,直接使用監測表單輸入的textInput值即可獲取到使用者value
handleSubmit(event){
alert(this.textInput.value)
event.preventDefault()
}複製程式碼
同時在state中將this轉出給標籤繫結事件處使用
constructor(props) {
super(props);
//讓state中的this能夠被handleSubmit外部函式訪問
this.handleSubmit = this.handleSubmit.bind(this)
}複製程式碼
狀態提升 單向資料流
【小案例】留言板
1.在評論區的元件中,我們需要將整個靜態評論列表傳給父元件
render(){
return(
<div className="commentlistcomp pl-5 pr-5 mt-5">
<label>評論列表</label>
<ul className="list-group contains">
{
this.props.comments.map((comment,index)=>
<div key={index} className="rows p-2">
<li className="list-group-item mb-3 ml-3">{comment}</li>
</div>
)
}
</ul>
</div>
)
}複製程式碼
2.在父元件的評論區子標籤中接收傳來的評論
<CommentList comments={comments}/>複製程式碼
3.在上個監測使用者表單輸入的提交元件中,建立p標籤,顯示已有多少條評論
將資料commentsLength props給父元件,資料和邏輯在父元件中定義
<p>已有{this.props.commentsLength}條評論</p>複製程式碼
4.在上個監測使用者表單輸入的提交元件,的按鈕提交事件中,定義onAddComment方法,並傳給父元件,目的:將使用者輸入內容作為引數傳出
handleSubmit(event){
//alert(this.textInput.value)
this.props.onAddComment(this.textInput.value)
this.textInput.value = ''
event.preventDefault()
}複製程式碼
5.在父元件的子標籤中,接收剛子元件傳來的評論數,和按鈕事件攜帶函式的使用者評論內容引數,
而評論數為陣列中的length數
<CommentBox commentsLength={comments.length}
onAddComment={this.addComment}
/>複製程式碼
6.在父元件裡先定義留言板子元件的評論陣列,並定義評論區一條內容
然後將提交事件this轉出,以備定義事件時使用
constructor(props){
super(props)
this.state = {
comments:['this is my first reply']
}
this.addComment = this.addComment.bind(this)
}複製程式碼
7.定義按鈕提交評論事件函式,由舊的評論數加新的評論陣列成
addComment(comment111){
this.setState({
//...舊的state.comments陣列展開
//最終comments陣列是舊+新組成
comments:[...this.state.comments,comment111]
})
}複製程式碼
最終效果
單向資料流:自上而下的資料流,在react中,任何可被改變的資料都只有一個資料來源;
和雙向繫結的區別:缺點:需要寫更多的程式碼,用回撥函式的方式改變資料狀態,
優點:很容易找bug
狀態提升:資料都交給子元件最近的父元件內管理