不要問自己需要什麼樣的人生,而要問自己想要成為什麼樣的人。
我們從前面的學習知道一個 React 元件不僅僅只包含 DOM 結構的,還應該樣式和 Javascript 邏輯的。這裡我們認識邏輯構造之事件處理。
這裡列舉了在 React 中事件的幾種繫結處理方式:
import React, { Component } from "react";
class App extends Component {
render () {
return (
<div>
<input/>
<button onClick={ ()=>{ console.log("第一種事件繫結處理方式") }}>Add-1</button>
<button onClick={ this.handleClick2 }>Add-2</button>
<button onClick={ this.handleClick3 }>Add-3</button>
<button onClick={ ()=>{ this.handleClick4() } }>Add-4</button>
</div>
)
}
handleClick2() {
console.log("第二種事件繫結處理方式")
}
handleClick3 = ()=>{
console.log("第三種事件繫結處理方式")
}
handleClick4 = ()=>{
console.log("第四種事件繫結處理方式")
}
}
export default App;
這裡重點說明下在事件和事件繫結繫結中 this 指向問題。
直接執行匿名函數,直接在 {} 中寫事件函數表示式。
寫法特點:
能直接存取:
class App extends Component {
// 定義屬性
value = 100
render () {
return (
<div>
<input/>
<button onClick={ ()=>{ console.log("第一種事件繫結處理方式", this.value) }}>Add-1</button>
</div>
)
}
寫法特點:this 指向和外部不一致,需要用 bind 修正 this 指向,不推薦使用。
<button onClick={ this.handleClick2 }>Add-2</button>
// 修正後:
<button onClick={ this.handleClick2.bind(this) }>Add-2</button>
handleClick2() {
// 異常,需要通過改變 this 指向解決
console.log("第二種事件繫結處理方式", this.value)
}
不能直接存取:
這裡存取類屬性 this.value 會報錯,我們可以列印出 this 看下它指向什麼,結果會是:undefined。為什麼 this 會丟失呢?記住一句話:函數中的 this 誰呼叫我,this 就指向誰。這裡點完按鈕後被 React 事件系統呼叫的,this 指向的應該是 React 事件系統。用於不會指向 App 這個範例。而這裡它也沒有指向 React 事件系統,而是丟了指向 undefined。哈哈哈....
寫法特點:this 指向和外部一直,沒有 this 指向問題,推薦使用。
<button onClick={ this.handleClick3 }>Add-3</button>
handleClick3 = ()=>{
console.log("第三種事件繫結處理方式", this.value)
}
這裡是箭頭函數,this 指向根本不關心誰呼叫的我,它永遠保持與外部作用域一樣的,它指向的 app 的範例。為什麼箭頭函數 this 指向就不關心誰呼叫的我呢?我也不知道.... 難到....
寫法特點:this 指向和外部一直,沒有 this 指向問題,符合誰呼叫我我指向誰。非常推薦使用這種寫法,引數傳遞很方便。
<button onClick={ ()=>{ this.handleClick4() } }>Add-4</button>
// 語法簡寫:
<button onClick={ ()=>this.handleClick4() }>Add-4</button>
// 有人說這裡是因為你寫成了箭頭函數了吧,即使他不寫成箭頭函數也沒關係,剛才講的原理,符合誰呼叫我我指向誰。
handleClick4 = ()=>{
console.log("第四種事件繫結處理方式", this.value)
}
整體有個問題: 要不要加小括號,不加不讓他自己主動執行,點選系統會呼叫、加小括號執行函數。加小闊號主動執行,點選後不執行 undefined。
var obj1 = {
name: "obj1",
getName() {
console.log(this.name)
}
}
var obj2 = {
name: "obj2",
getName() {
console.log(this.name)
}
}
// this.name 誰呼叫我我指向誰
obj1.getName() // 結果 obj1
obj2.getName() // 結果 obj2
// call, reply :修改 obj1 getName 中 this 指向 obj2
obj1.getName.call(obj2) // 結果 obj2
obj2.getName() // 結果 obj2
React 中事件繫結沒有繫結到具體的 DOM 節點(元素)身上。它採用的是一種事件代理的模式,繫結在根節點身上。繫結到每一個 DOM 節點身上是很消耗記憶體的。
React 模擬了一套事件冒泡機制,等冒泡到根節點上通過 target 事件源找到是那個元素真實觸發的,然後從這個觸發的元素到頂點所有節點都去查一查,有沒有一個叫 onClick 屬性,如果有就把這個 onClick 事件給執行了,完整模擬冒泡的流程,即模擬系統事件機制。其不需要考慮解綁、移除事件等,只有節點從頁面中沒了,onClick 根本就不會再有了,沒有繫結只有節點沒了 onClick 就沒了。
Event 物件,和普通瀏覽器一樣,事件 handler 會被自動傳入一個 event 物件,這個物件和普通的瀏覽器 event 物件所包含的方法和屬性都基本一致。不同的是 React 中的 event 物件並不是瀏覽器提供的,而是它自己內部所構建的。它同樣具有 event . stoppropagation、event.preventDefault 這種常用的方法。