React事件處理超詳細(xì)介紹
1. 事件綁定
React 元素的事件處理和 DOM 元素的很相似,但是有一點(diǎn)語(yǔ)法上的不同:
React 事件的命名采用小駝峰式,而不是純小寫。
onClick
=> onChange
使用 JSX 語(yǔ)法時(shí)你需要傳入一個(gè)函數(shù)作為事件處理函數(shù),而不是一個(gè)字符串。
onClick={this.fn}
// 綁定實(shí)現(xiàn)方法一定要用 {函數(shù)或方法};注意函數(shù)或方法不能用小括號(hào)
類組件與函數(shù)組件綁定事件是差不多的,只是在類組件中綁定事件函數(shù)的時(shí)候需要用到 this,代表指向當(dāng)前的類的引用,在函數(shù)中不需要調(diào)用 this
1.1 函數(shù)組件
import React, { Component } from 'react' // 函數(shù)組件中沒有this指向問題 const App = () => { let num = 1 const clickFn = () => { console.log(num++) } // const clickFn = () => () => { // console.log(num++) // } return ( <div> {/* 普通的值,它不具備響應(yīng)式,所以你修改數(shù)據(jù)后,視圖是不會(huì)更新的 */} <h3>App組件 -- {num}</h3> {/* 綁定點(diǎn)擊事件 */} {/* 一般情況下,綁定的實(shí)現(xiàn)方法是不會(huì)加小括號(hào),如果要加小括號(hào),則定義綁定方法時(shí),一定要返回一函數(shù) */} <button onClick={clickFn}>++++</button> {/* <button onClick={clickFn()}>++++</button> */} </div> ) } export default App
1.2 類組件
import React, { Component } from 'react' class App extends Component { num = 100 todos = [] // 建議使用箭頭函數(shù)定義成員屬性 addNum = () => { // 同步修改成員屬性中的數(shù)據(jù),但是視圖不更新 this.num++ // 類組件中提供一個(gè)方法,可以強(qiáng)制讓視圖更新 this.forceUpdate() } // react事件,在沒有寫小括號(hào)的時(shí)候會(huì)主動(dòng)的把event對(duì)象傳給你 onEnter = evt => { if (evt.keyCode === 13) { this.todos.push({ id: Date.now(), title: evt.target.value.trim(), done: false }) evt.target.value = '' // 通知視圖更新 this.forceUpdate() } } render() { return ( <div> <h3>{this.num}</h3> <ul> {this.todos.map(item => ( <li key={item.id}>{item.title}</li> ))} </ul> {/* 類組件中綁定方法,有this指向問題 */} <button onClick={this.addNum}>++++</button> <input type="text" onKeyUp={this.onEnter} /> </div> ) } } export default App
2. 合成事件
概述:
在原生 Dom 事件( html 中),假如我們給 button 按鈕綁定點(diǎn)擊事件,是綁定在 button 上去的。而這種情況在 React 中,不會(huì)在 button 上綁定事件,React 會(huì)將 Dom 中的事件進(jìn)行收集,然后將事件委托到容器中(id=root,即掛載點(diǎn))。
在 React16 及之前,React 將所有的事件都委托到 document 當(dāng)中去,而在 React17 及之后,React 將所有的事件都委托到掛載點(diǎn)中去了。
為什么出現(xiàn)這個(gè)技術(shù)?
- 性能優(yōu)化:使用事件代理統(tǒng)一接收原生事件的觸發(fā),從而可以使得真實(shí) DOM 上不用綁定事件。React 挾持事件觸發(fā)可以知道用戶觸發(fā)了什么事件,是通過(guò)什么原生事件調(diào)用的真實(shí)事件。這樣可以通過(guò)對(duì)原生事件的優(yōu)先級(jí)定義進(jìn)而確定真實(shí)事件的優(yōu)先級(jí),再進(jìn)而可以確定真實(shí)事件內(nèi)觸發(fā)的更新是什么優(yōu)先級(jí),最終可以決定對(duì)應(yīng)的更新應(yīng)該在什么時(shí)機(jī)更新。
- 分層設(shè)計(jì):解決跨平臺(tái)問題,抹平瀏覽器差異和平臺(tái)差異。
3. 事件傳參的3種不同寫法
import React, { Component } from 'react'; class App extends Component { // 在react中事件對(duì)象,它是通過(guò)事件參數(shù)傳給方法的 // 參數(shù)空著,會(huì)默認(rèn)綁定事件 fn = () => { console.log('fn') } // 又想傳參,又想觸發(fā)事件得這么寫,evt會(huì)自動(dòng)映射過(guò)來(lái),注意最后一個(gè)箭頭前只能是 evt 對(duì)象 fn1 = num => evt => { console.log(num, evt); } // 這種寫法是可以隨意變更 evt 對(duì)象傳參過(guò)來(lái)的位置 fn2 = (num, evt) => { console.log(num, evt); } render() { return ( <div> {/* onClick={ 注意:花括號(hào)里是函數(shù)的表達(dá)式,而不是函數(shù)的調(diào)用 } */} <button onClick={this.fn}>綁定點(diǎn)擊事件</button> <button onClick={this.fn1(100)}>綁定點(diǎn)擊事件</button> <button onClick={evt => this.fn2(200, evt)}>綁定點(diǎn)擊事件</button> </div> ); } } export default App;
4. this 指向問題
在JSX事件函數(shù)方法中的 this,默認(rèn)不會(huì)綁定 this 指向。如果你忘記綁定,當(dāng)你調(diào)用這方法的時(shí)候,this 的值為 undefined。所以使用時(shí)一定要綁定好 this 的指向。
this 指向針對(duì)的是類組件,函數(shù)組件沒有 this 問題,因?yàn)楹瘮?shù)沒有 this 。
利用 bind 函數(shù)綁定 this 指向:
import React, { Component } from 'react'; class App extends Component { num = 100 // 類的構(gòu)造函數(shù),它只執(zhí)行1次,在初始化 // constructor(props) { // super(props); // // 在構(gòu)建函數(shù)中統(tǒng)一的把事件方法this綁定好 // this.addNum = this.addNum.bind(this) // } // 在react事件綁定的類組件中,默認(rèn)情況this指向會(huì)可能存在指向問題 undefined // 在綁定事件中綁定this調(diào)用函數(shù)時(shí)的寫法 addNum(n = 1) { this.num += n this.forceUpdate() } // 構(gòu)造函數(shù)中綁定this調(diào)用函數(shù)時(shí)的寫法,因?yàn)椴粋髦档谝粋€(gè)參數(shù)會(huì) // addNum(evt, n = 1) { // this.num += n // this.forceUpdate() // } render() { return ( <div> <h3>{this.num}</h3> {/* 在此處可以使用bind來(lái)綁定this指向(this指向 App 實(shí)例),且還可以傳參數(shù) */} {/* 此方案在使用中,較多 */} {/* <button onClick={this.addNum.bind(this)}>累加</button> */} <button onClick={this.addNum.bind(this, 2)}>累加</button> {/* 如果你這樣寫,又想this指向?qū)Γ瑒t一定要在構(gòu)造函數(shù)中,解決好this指向 */} {/* <button onClick={this.addNum}>累加</button> */} </div> ); } } export default App;
注意:使用 bind 綁定 this 共有兩種方案,一種是調(diào)用函數(shù)時(shí)綁定,一種是在構(gòu)造函數(shù)中統(tǒng)一綁定。
利用箭頭函數(shù)解決 this 指向:
import React, { Component } from 'react'; class App extends Component { num = 100 // 類的構(gòu)造函數(shù),它只執(zhí)行1次,在初始化 // constructor(props) { // super(props); // // 在構(gòu)建函數(shù)中統(tǒng)一的把事件方法this綁定好 // this.addNum = this.addNum.bind(this) // } // 在react事件綁定的類組件中,默認(rèn)情況this指向會(huì)可能存在指向問題 undefined // 在綁定事件中綁定this調(diào)用函數(shù)時(shí)的寫法 addNum(n = 1) { this.num += n this.forceUpdate() } // 構(gòu)造函數(shù)中綁定this調(diào)用函數(shù)時(shí)的寫法,因?yàn)椴粋髦档谝粋€(gè)參數(shù)會(huì) // addNum(evt, n = 1) { // this.num += n // this.forceUpdate() // } render() { return ( <div> <h3>{this.num}</h3> {/* 在此處可以使用bind來(lái)綁定this指向(this指向 App 實(shí)例),且還可以傳參數(shù) */} {/* 此方案在使用中,較多 */} {/* <button onClick={this.addNum.bind(this)}>累加</button> */} <button onClick={this.addNum.bind(this, 2)}>累加</button> {/* 如果你這樣寫,又想this指向?qū)?,則一定要在構(gòu)造函數(shù)中,解決好this指向 */} {/* <button onClick={this.addNum}>累加</button> */} </div> ); } } export default App;
到此這篇關(guān)于React事件處理超詳細(xì)介紹的文章就介紹到這了,更多相關(guān)React事件處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
webpack 2的react開發(fā)配置實(shí)例代碼
本篇文章主要介紹了webpack 2的react開發(fā)配置實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07一文搞懂?React?18?中的?useTransition()?與?useDeferredValue()
這篇文章主要介紹了一文搞懂?React?18?中的?useTransition()與useDeferredValue(),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09react如何實(shí)現(xiàn)一個(gè)密碼強(qiáng)度檢測(cè)器詳解
這篇文章主要給大家介紹了關(guān)于react如何實(shí)現(xiàn)一個(gè)密碼強(qiáng)度檢測(cè)器的相關(guān)資料,使用這個(gè)密碼強(qiáng)度器后可以幫助大家提高在線帳號(hào)、個(gè)人信息的安全性,需要的朋友可以參考下2021-06-06React實(shí)現(xiàn)監(jiān)聽粘貼事件并獲取粘貼板中的截圖
這篇文章主要介紹了React實(shí)現(xiàn)監(jiān)聽粘貼事件并獲取粘貼板中的截圖方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08React教程之Props驗(yàn)證的具體用法(Props Validation)
這篇文章主要介紹了React教程之Props驗(yàn)證的具體用法(Props Validation),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09詳解如何封裝和使用一個(gè)React鑒權(quán)組件
JavaScript?和?React?提供了靈活的事件處理機(jī)制,特別是通過(guò)利用事件的捕獲階段來(lái)阻止事件傳播可以實(shí)現(xiàn)精細(xì)的權(quán)限控制,本文將詳細(xì)介紹這一技術(shù)的應(yīng)用,并通過(guò)實(shí)踐案例展示如何封裝和使用一個(gè)?React?鑒權(quán)組件,需要的可以參考下2024-03-03react-router?v6實(shí)現(xiàn)權(quán)限管理+自動(dòng)替換頁(yè)面標(biāo)題的案例
這篇文章主要介紹了react-router?v6實(shí)現(xiàn)權(quán)限管理+自動(dòng)替換頁(yè)面標(biāo)題,這次項(xiàng)目是有三種權(quán)限,分別是用戶,商家以及管理員,這次寫的權(quán)限管理是高級(jí)權(quán)限能訪問低級(jí)權(quán)限的所有頁(yè)面,但是低級(jí)權(quán)限不能訪問高級(jí)權(quán)限的頁(yè)面,需要的朋友可以參考下2023-05-05關(guān)于React動(dòng)態(tài)修改元素樣式的三種方式
這篇文章主要介紹了關(guān)于React動(dòng)態(tài)修改元素樣式的三種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08