文章目錄
- 事件處理
- React事件處理函式
- 事件流
- 事件委托
- 收集表單資料
- 非受控組件
- 受控組件
- 函式柯里化
事件處理
在React中獲取虛擬組件中的標簽的值
- 使用組件的 refs屬性
- 在虛擬組件的標簽中定義事件,在事件中通過 箭頭函式 獲取標簽的值
- 使用事件物件——event
事件處理:
- 通過onXxx屬性指定事件處理函式(注意大小寫)
- React使用的是自定義(合成)事件, 而不是使用的原生DOM事件 ———為了更好的兼容性
- React中的事件是通過事件委托方式處理的(委托給組件最外層的元素) ————為了高效
- 通過event.target得到發生事件的DOM元素物件 ———不要過度使用ref
使用event.target屬性:
//創建組件
class Demo extends React.Component{
myRef = React.createRef()
//展示輸入框的資料
showData = (event)=>{
alert(event.target.value);
}
render(){
return(
<div>
<input onBlur={this.showData} type="text" placeholder="失去焦點提示資料"/>
</div>
)
}
}
//渲染組件到頁面
ReactDOM.render(<Demo/>,document.getElementById('test'))
React事件處理和Dom事件處理區別:
1、在 語法 上的不同點:
-
React事件名采用駝峰命名法,即事件名首字母大寫,如onclick(Dom)——onClick(React)
-
回應事件的函式在React中以 物件方式 賦值,Dom是以 字串方式 賦值
<button onclick= ' clickMe( ) '>提交</button> ——Dom方式 <button onClick={ clickMe( ) }>提交</button> ——React方式
2、在阻止事件的默認行為有區別:React事件是合成的,DOM事件是原生的
- Dom:回傳false
- React:顯示的呼叫事件物件event.preventDefault
React事件處理函式
-
1、使用ES6的箭頭函式
class MyComponent extends React.Component{ constructor(props){ super(props); this.state={ number:0 } handleClick=()=>{ ++this.state.number; console.log(this.state.number); } render(){ return( <div> <button type='button' onClick={this.handleClick}>點我</button> </div> ) } } ReactDOM.render(<MyComponent/>,document.getElementById('example')); -
2、在組件中定義事件處理函式
class MyComponent extends React.Component{ constructor(props){ super(props); this.state={ number:0 } this.handleClick=this.handleClick.bind(this); } handleClick(){ ++this.state.number; console.log(this.state.number); } render(){ return( <div> <button type='button' onClick={this.handleClick}>點我</button> </div> ) } } ReactDOM.render(<MyComponent/>,document.getElementById('example'));- 注:這種方法的好處是每次render渲染都不會重新創建一個回呼函式,沒有額外的性能損失,但是如果在一個組件中有很多的事件函式時這種在建構式中系結this的方法會顯得繁瑣
-
3、在給事件賦值時系結this
class MyComponent extends React.Component{ constructor(props){ super(props); this.state={ number:0 } } handleClick(){ ++this.state.number; console.log(this.state.number); } render(){ return( <div> <button type='button' onClick={this.handleClick.bind(this)}>點我</button> </div> ) } } ReactDOM.render(<MyComponent/>,document.getElementById('example'));- 注:但是此方法在每次render時都會重新創建一個新的函式,性能有一定的損失,但在事件處理函式需要傳引數時,這種方法就比較好
事件流
在該示例中,3個div嵌套顯示,并且每個元素上均系結onClick事件,當用戶點擊紅色區域的div元素時,可以看到,控制臺先后輸出了child -> parent -> ancestor,這是因為在React的事件處理系統中,默認的事件流就是冒泡,
const style={
child:{
width:'100px',
height:'100px',
background:'red'
},
parent:{
width:'150px',
height:'150px',
background:'blue'
},
ancestor:{
width:'200px',
height:'200px',
background:'green'
}
}
class Example extends React.Component{
render(){
return(
<div onClickCapture={()=> console.log('ancestor')} style={style.ancestor}>
<div onClickCapture={ ()=> console.log('parent')} style={style.parent}>
<div onClickCapture={ ()=> console.log('child')} style={style.child}></div>
</div>
</div>
)
}
}
ReactDOM.render(<Example/>,document.getElementById('example'));

- React默認的事件觸發方式:冒泡方式
- 若將事件觸發改為捕獲方式:需要在事件名后帶上 Capture 后綴
<div onClickCapture={()=> console.log('ancestor')} style={style.ancestor}>
<div onClickCapture={ ()=> console.log('parent')} style={style.parent}>
<div onClickCapture={ ()=> console.log('child')} style={style.child}></div>
</div>
</div>
事件委托
在合成事件系統中,所有的事件都是系結在document元素上,即雖然在某個React元素上系結了事件,但是,最后事件都委托給document統一觸發,因此,在合成事件中只能阻止合成事件中的事件傳播
React 阻止的事件流,并沒有阻止真正DOM元素的事件觸發,還是按照冒泡的方式,層層將事件交給上級元素進行處理,最后事件傳播到docuement,觸發合成事件,在合成事件中,child觸發時,e.stopPropagation() 被呼叫,合成事件中的事件被終止,因此,合成事件中的stopPropagation無法阻止事件在真正元素上的傳遞,它只阻止合成事件中的事件流,相反,如果系結一個真正的事件,那么,合成事件則會被終止,
- 默認事件流是冒泡的,所有事件統一由document觸發,在React中阻止冒泡方法是呼叫e.stopPropagation()
- React的合成事件是可以找到原生的事件物件
- React中的合成事件中只有一個全域物件event,該物件不是原生的event,但通過它可以獲得event物件的部分屬性,每個事件觸發完后React的全域物件event就會被清空,因此不能在異步操作使用
事件型別:

收集表單資料
非受控組件
表單資料由DOM本身處理,即不受setState()的控制,與傳統的HTML表單輸入相似,input輸入值即顯示最新值(使用 ref 從DOM獲取表單值),即不受React控制改變表單元素提交的值的方式,稱為:“非受控組件”
class Login extends React.Component{
handleSubmit = (event)=>{
event.preventDefault() //阻止表單提交
const {username,password} = this
alert(`你輸入的用戶名是:${username.value},你輸入的密碼是:${password.value}`)
}
render(){
return(
<form onSubmit={this.handleSubmit}>
用戶名:<input ref={c => this.username = c} type="text" name="username"/>
密碼:<input ref={c => this.password = c} type="password" name="password"/>
<button>登錄</button>
</form>
)
}
}
//渲染組件
ReactDOM.render(<Login/>,document.getElementById('test'))
受控組件
在HTML中,標簽
<input>、<textarea>、<select>的值的改變通常是根據用戶輸入進行更新,在React中,可變狀態通常保存在組件的狀態屬性中,并且只能使用 setState() 更新,而呈現表單的React組件也控制著在后續用戶輸入時該表單中發生的情況,以這種由React控制的輸入表單元素而改變其值的方式,稱為:“受控組件”,
class Login extends React.Component{
//初始化狀態
state = {
username:'', //用戶名
password:'' //密碼
}
//保存用戶名到狀態中
saveUsername = (event)=>{
this.setState({username:event.target.value})
}
//保存密碼到狀態中
savePassword = (event)=>{
this.setState({password:event.target.value})
}
//表單提交的回呼
handleSubmit = (event)=>{
event.preventDefault() //阻止表單提交
const {username,password} = this.state
alert(`你輸入的用戶名是:${username},你輸入的密碼是:${password}`)
}
render(){
return(
<form onSubmit={this.handleSubmit}>
用戶名:<input onChange={this.saveUsername} type="text" name="username"/>
密碼:<input onChange={this.savePassword} type="password" name="password"/>
<button>登錄</button>
</form>
)
}
}
//渲染組件
ReactDOM.render(<Login/>,document.getElementById('test'))
受控和非受控元素都有其優點,根據具體情況選擇
| 特征 | 非受控制 | 受控 |
|---|---|---|
| 一次性檢索(例如表單提交) | √ | √ |
| 及時驗證 | × | √ |
| 有條件的禁用提交按鈕 | × | √ |
| 執行輸入格式 | × | √ |
| 一個資料的幾個輸入 | × | √ |
| 動態輸入 | × | √ |
函式柯里化
高階函式:如果一個函式符合下面2個規范中的任何一個,那該函式就是高階函式,
- 若A函式,接收的引數是一個函式,那么A就可以稱之為高階函式
- 若A函式,呼叫的回傳值依然是一個函式,那么A就可以稱之為高階函式
常見的高階函式有:Promise、setTimeout、arr.map()等等
函式的柯里化:通過函式呼叫繼續回傳函式的方式,實作多次接收引數最后統一處理的函式編碼形式,
function sum(a){
return(b)=>{
return (c)=>{
return a+b+c
}
}
}
函式柯里化的實作
class Login extends React.Component{
//初始化狀態
state = {
username:'', //用戶名
password:'' //密碼
}
//保存表單資料到狀態中
saveFormData = (dataType)=>{
return (event)=>{
this.setState({[dataType]:event.target.value})
}
}
//表單提交的回呼
handleSubmit = (event)=>{
event.preventDefault() //阻止表單提交
const {username,password} = this.state
alert(`你輸入的用戶名是:${username},你輸入的密碼是:${password}`)
}
render(){
return(
<form onSubmit={this.handleSubmit}>
用戶名:<input onChange={this.saveFormData('username')} type="text" name="username"/>
密碼:<input onChange={this.saveFormData('password')} type="password" name="password"/>
<button>登錄</button>
</form>
)
}
}
//渲染組件
ReactDOM.render(<Login/>,document.getElementById('test'))
不用柯里化的實作
class Login extends React.Component{
//初始化狀態
state = {
username:'', //用戶名
password:'' //密碼
}
//保存表單資料到狀態中
saveFormData = (dataType,event)=>{
this.setState({[dataType]:event.target.value})
}
//表單提交的回呼
handleSubmit = (event)=>{
event.preventDefault() //阻止表單提交
const {username,password} = this.state
alert(`你輸入的用戶名是:${username},你輸入的密碼是:${password}`)
}
render(){
return(
<form onSubmit={this.handleSubmit}>
用戶名:<input onChange={event => this.saveFormData('username',event) } type="text" name="username"/>
密碼:<input onChange={event => this.saveFormData('password',event) } type="password" name="password"/>
<button>登錄</button>
</form>
)
}
}
//渲染組件
ReactDOM.render(<Login/>,document.getElementById('test'))
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/299694.html
標籤:其他
上一篇:??最新??2021國賽??B乙醇偶合制備 C4 烯烴??C生產企業原材料的訂購與運輸??E中藥材的鑒別??全套(LW,DM)
下一篇:node中http模塊的使用
