React的事件處理你了解嗎
一、React的事件處理
1、與DOM事件處理的不同之處
(1)React事件的命名方式:小駝峰方式,DOM的命名方式是小寫
例如:DOM的命名:onclick
React的命名:onClick
(2)事件處理函數(shù)是以對象的方式賦值,而不是以字符串的方式賦值
例如:DOM以字符串方式:onclick = "handleClick()"
React以對象方式:onClick = { handleClick }
(3)阻止默認(rèn)事件的方式不同
DOM通過返回false來阻止: <a href="www.baidu.com" οnclick="javascript:return false;">百度</a>
React需要顯式調(diào)用e.preventDefault來阻止
2、React中事件處理函數(shù)的定義
(1)使用ES6的箭頭數(shù)
①在render函數(shù)中使用箭頭函數(shù):
Ⅰ、優(yōu)點:不用在構(gòu)造函數(shù)中綁定this
Ⅱ、缺點:當(dāng)函數(shù)的邏輯比較復(fù)雜時,render就顯得臃腫,無法直觀的看到組件的UI結(jié)構(gòu),代碼可讀性差
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件處理函數(shù)-->在render中使用箭頭函數(shù)</title>
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
let root = document.getElementById('root');
//1.創(chuàng)建一個類組件
class MyComponent extends React.Component{
constructor(props){
super(props)
this.state={
msg: '小森同學(xué)'
}
}
render(){
return (
<div>
<button onClick= { ()=>{ console.log(this.state.msg)} } >點我</button>
</div>
)
}
}
//2.進(jìn)行渲染
ReactDOM.render(<MyComponent/>,root)
</script>
</body>
</html>②使用class fields語法:將箭頭函數(shù)賦給類的屬性
Ⅰ、優(yōu)點:不用在構(gòu)造函數(shù)中綁定this,在render函數(shù)中調(diào)用簡單
<body>
<div id="root"></div>
<script type="text/babel">
let root = document.getElementById('root');
//1.創(chuàng)建一個類組件
class MyComponent extends React.Component{
constructor(props){
super(props)
this.state={
msg: '小沈同學(xué)',
number: 0
}
}
handleClick = ()=>{ //將箭頭函數(shù)賦給類的屬性
console.log(this.state.msg) //將一個箭頭函數(shù)賦值為handleClick,handleClick是MyComponent的一個屬性
}
render(){
console.log('render')
return (
<div>
<button onClick= { this.handleClick } >點我</button> //調(diào)用這個屬性
</div>
)
}
}
//2.進(jìn)行渲染
ReactDOM.render(<MyComponent/>,root)
</script>
</body>(2)在構(gòu)造函數(shù)中進(jìn)行綁定:將事件處理函數(shù)作為類的成員函數(shù)
注意:在定義事件處理函數(shù)時,是無法識別this(即this是undefined的),必須在構(gòu)造函數(shù)中綁定this
①、優(yōu)點:在render函數(shù)調(diào)用時不需要重新創(chuàng)建事件處理函數(shù)
②、缺點:當(dāng)事件處理很多時,構(gòu)造函數(shù)就顯的很繁瑣
<body>
<div id="root"></div>
<script type="text/babel">
let root = document.getElementById('root');
//1.創(chuàng)建一個類組件
class MyComponent extends React.Component{
constructor(props){
super(props)
this.state={
msg: '小沈同學(xué)',
number: 0
}
this.add = this.add.bind(this) //this指針綁定到函數(shù)add里面去
}
handleClick = ()=>{
console.log(this.state.msg)
}
add(){ //如果上述不綁定this,那么add函數(shù)里的this將無法識別
let num = this.state.number
num++
this.setState({
number: num
})
console.log(this.state.number)
}
render(){
console.log('render')
return (
<div>
<button onClick= { this.handleClick } >點我</button>
<button onClick= { this.add }>Number++</button>
</div>
)
}
}
//2.進(jìn)行渲染
ReactDOM.render(<MyComponent/>,root)
</script>
</body>(3)在render函數(shù)中綁定this
①、優(yōu)點:在調(diào)用事件處理函數(shù)時,傳參比較方便
②、缺點:每次調(diào)用render函數(shù)時都重新綁定,導(dǎo)致性能下降
<body>
<div id="root"></div>
<script type="text/babel">
let root = document.getElementById('root');
//1.創(chuàng)建一個類組件
class MyComponent extends React.Component{
constructor(props){
super(props)
this.state={
msg: '小沈同學(xué)',
number: 0
}
// this.add = this.add.bind(this) //this指針綁定到函數(shù)add里面去
}
handleClick = ()=>{
console.log(this.state.msg)
}
add(){ //如果上述不綁定this,那么add函數(shù)里的this將無法識別
let num = this.state.number
num++
this.setState({
number: num
})
console.log(this.state.number)
}
render(){
console.log('render')
return (
<div>
<button onClick= { this.handleClick } >點我</button>
<button onClick= { this.add.bind(this) }>Number++</button>
</div>
)
}
}
//2.進(jìn)行渲染
ReactDOM.render(<MyComponent/>,root)
</script>
</body>(4)React中事件處理函數(shù)
幾種方式的比較
影響constructor函數(shù)中bind使用class fields語法render中使用箭頭函數(shù)render中使用bindrender時生成新函數(shù)否否是是性能無影響無影響有影響有影響可直接攜帶參數(shù)否否是是簡潔性不好好好好
(5)注意事項
①React事件的命名采用小駝峰式(camelCase),而不是純小寫。且事件名稱之后不能加(),否則會直接執(zhí)行
②不能通過返回false的方式阻止默認(rèn)行為,必須顯示的使用preventDefault
③必須謹(jǐn)慎對待JXS回調(diào)函數(shù)中的this,在JavaScript中,class(類)的方法默認(rèn)不會綁定this。如果忘記綁定this.textChange并把它傳入onChange,當(dāng)調(diào)用這個函數(shù)的時候,this的值為undefined。如果覺得使用bind麻煩,還可以使用箭頭函數(shù)。
3、事件處理中的參數(shù)傳遞
(1)直接傳遞參數(shù)
①在構(gòu)造函數(shù)中給事件處理函數(shù)綁定this,調(diào)用事件處理函數(shù)時直接傳參
<div id="root"></div>
<script type="text/babel">
let root = document.getElementById('root');
//1.定義類組件
class Clock extends React.Component{
constructor(props){
super(props)
this.state= {
list:[
{
id: 111,
msg: '小森'
},
{
id: 222,
msg: '小沈'
},
{
id: 333,
msg: '小顧'
}
],
msg: '編號:'
}
this.handleClick = this.handleClick.bind(this)
}
handleClick(id){ //事件處理函數(shù)
alert("編號:"+id)
}
render(){
//獲取狀態(tài)屬性值
const { list } = this.state
return (
<div>
{
list.map((item)=>
<button onClick={ ()=>{this.handleClick(item.id)}} key={item.id}>{item.msg}</button>
)
}
</div>
)
}
}
//2.渲染
ReactDOM.render(<Clock/>,root)
</script>注意:在箭頭函數(shù)中調(diào)用事件處理函數(shù)時不需要綁定this
②在render函數(shù)中調(diào)用事件處理函數(shù)時進(jìn)行this的綁定
<div id="root"></div>
<script type="text/babel">
let root = document.getElementById('root');
//1.定義類組件
class Clock extends React.Component{
constructor(props){
super(props)
this.state= {
list:[
{
id: 111,
msg: '小森'
},
{
id: 222,
msg: '小沈'
},
{
id: 333,
msg: '小顧'
}
],
msg: '編號:'
}
}
handleClick(id){ //事件處理函數(shù),e表示觸發(fā)事件的對象,成員函數(shù)
let str = this.state.msg
alert(str + id)
}
render(){
//獲取狀態(tài)屬性值
const { list } = this.state
return (
<div>
{
list.map((item)=>
<button onClick={ this.handleClick.bind(this,item.id) } key={item.id}>{ item.msg }</button>
)
}
</div>
)
}
}
//2.渲染
ReactDOM.render(<Clock/>,root)
</script>(2)在定義UI控件時使用data自定義屬性,在事件處理函數(shù)中通過'e.target.dataset.屬性名'來獲取UI控件中的data屬性值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件處理中的參數(shù)傳遞</title>
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
let root = document.getElementById('root');
//1.定義類組件
class Clock extends React.Component{
constructor(props){
super(props)
this.state= {
list:[
{
id: 111,
msg: '小森'
},
{
id: 222,
msg: '小沈'
},
{
id: 333,
msg: '小顧'
}
],
msg: '編號:'
}
}
handleClick(e){ //事件處理函數(shù),e表示觸發(fā)事件的對象
let str = this.state.msg
alert(str + e.target.dataset.count)
//事件處理對象event,通過event可以得到target目標(biāo)對象,就是那個button。dataset,得到自定義屬性的集合,在集合里找到count
}
render(){
//獲取狀態(tài)屬性值
const { list } = this.state
return (
<div>
{
list.map((item)=>
<button
onClick={ this.handleClick.bind(this) }
key={item.id}
data-count = { item.id} //標(biāo)簽的自定義屬性用'data-'開頭后跟自定義屬性名
>{ item.msg }</button>
)
}
</div>
)
}
}
//2.渲染
ReactDOM.render(<Clock/>,root)
</script>
</body>
</html>4、事件流
(1)React的事件流默認(rèn)是冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件流</title>
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
let root = document.getElementById('root')
//1.定義CSS樣式
const style = {
child: {
width: '100px',
height: '100px',
backgroundColor: 'red'
},
parent: {
width: '150px',
height: '150px',
backgroundColor: 'blue'
},
ancestor: {
width: '200px',
height: '200px',
backgroundColor: 'green'
}
}
//2.定義類組件
class App extends React.Component{
render(){
return (
<div
onClick= { ()=>{ console.log('ancestor')}}
style = { style.ancestor }
>
<div
onClick={ ()=>{ console.log('parent')}}
style = { style.parent }
>
<div
onClick={ (e)=>{
console.log('child')
e.stopPropagation() //阻止冒泡
}}
style = {style.child }
>
</div>
</div>
</div>
)
}
}
//3.渲染
ReactDOM.render(<App/>,root)
</script>
</body>
</html>
//輸出child,parent,ancestor(2)React中使用捕獲方式:事件類型后面加一個后綴Capture
先由document找到最外層綠色的,然后傳給藍(lán)色,然后傳給紅色。所以工具中輸出的順序是(ancestor,parent,child)
5、事件對象
雖然React事件是合成事件,但是在事件處理中可以獲取事件對象的
(1)在React事件處理中有一個全局事件對象
event對象,每次事件觸發(fā)后(事件處理函數(shù)調(diào)用完成后),就會清空event對象當(dāng)下一次事件觸發(fā)時重新獲取該對象。該對象不是原生(DOM)的event對象,但是可以通過該對象獲取原生對象的部分屬性
<div id="root"></div>
<script type="text/babel">
let root = document.getElementById('root')
//1.定義樣式規(guī)則
const style = {
"mydiv": {
width: '150px',
height: '150px',
backgroundColor: 'red'
}
}
//2.定義類組件
class App extends React.Component{
constructor(props){
super(props)
this.state = {
x: 0,
y: 0
}
}
render(){
return (
<div>
<div style = { style['mydiv']} //以數(shù)組的方式設(shè)置樣式
onClick= { (event)=> { //'event'對象不是原生的event,但是可以通過event來獲取原生的事件對象的部分屬性
const { clientX,clientY } = event
this.setState({
x: event.clientX,
y: event.clientY
})
>
X: {this.state.x},Y: { this.state.y }
</div>
</div>
)
}
}
//3.渲染
ReactDOM.render(<App />,root)
</script>(2)在異步操作中獲取event
問題:當(dāng)事件觸發(fā)、響應(yīng)結(jié)束后,event對象會被清空,但是異步數(shù)據(jù)還沒有得到,在得到異步數(shù)據(jù)之后再去訪問 event對象的屬性就會報錯。
解決辦法:先將event對象的某些屬性值保存起來,得到異步數(shù)據(jù)之后再來使用這些屬性值
<div id="root"></div>
<script type="text/babel">
let root = document.getElementById('root')
//1.定義樣式規(guī)則
const style = {
"mydiv": {
width: '150px',
height: '150px',
backgroundColor: 'red'
}
}
//2.定義類組件
class App extends React.Component{
constructor(props){
super(props)
this.state = {
x: 0,
y: 0
}
}
render(){
return (
<div>
<div style = { style['mydiv']} //以數(shù)組的方式設(shè)置樣式
onClick= { (event)=> { //'event'對象不是原生的event,但是可以通過event來獲取原生的事件對象的部分屬性
const { clientX,clientY } = event //定義變量,將event保存起來
setTimeout(()=>{ //下次觸發(fā)時就可以得到保存在變量中的值
this.setState({
x: clientX,
y: clientY
})
},1000)
}}
>
X: {this.state.x},Y: { this.state.y }
</div>
</div>
)
}
}
//3.渲染
ReactDOM.render(<App />,root)
</script>總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
ReactNative踩坑之配置調(diào)試端口的解決方法
本篇文章主要介紹了ReactNative踩坑之配置調(diào)試端口的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
React?+?Typescript領(lǐng)域初學(xué)者的常見問題和技巧(最新)
這篇文章主要介紹了React?+?Typescript領(lǐng)域初學(xué)者的常見問題和技巧,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06
關(guān)于react ant 組件 Select下拉框 值回顯的問題
這篇文章主要介紹了關(guān)于react ant 組件 Select下拉框 值回顯的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08

