終究都要學 React 何不現在學呢? - React 基礎 - 事件處理 - (5)

前言

接著來聊聊 React 的事件處理,畢竟事件處理這件事情我們在開發上是非常常見的。

Vue 事件處理

一開始我們先來快速聊一下 Vue 的部分。

Vue 本身是採用 v-on:事件名稱="函式" 的概念撰寫,以點擊事件(click)並觸發一個打招呼函式(sayHi)當作舉例

1
<a href="https://israynotarray.com/" v-on:click="sayHi">點我</a>

但是實戰上其實我們很少寫 v-on: 大多都是使用事件修飾符 「@」來取代 v-on:

1
<a href="https://israynotarray.com/" @click="sayHi">點我</a>

而上方就是我們最基本使用 Vue 的事件處理方式。

Vue 事件修飾符

上面的範例你會發現當你點了之後會先跳出警告視窗,之後畫面就被個轉到我的部落格 (其實這是一個計畫通概念)

部落格

其實這個問題是連結本身有預設行為的關係,也就是重新轉址導向href 網址,如同使用表單送出時的 action 路徑相同,如果要解決這個問題的話,我們就要使用 Vue 的「事件修飾符」,那麼事件修飾符非常多,所以這邊就只介紹一個也就是 .prevent,只要你在 @click 後方補個 .prevent 就可以解決重新轉址導向的問題

1
<a href="https://israynotarray.com/" @click.prevent="sayHi">點我</a>

透過事件修飾符就可以避免我們點擊連結就會跳轉的問題了。

前面這邊快速回顧與了解 Vue 的事件處理、事件修飾符後,React 呢?React 又是如何呢?所以我們接著下去。

React 事件處理

前面我們快速了回顧 Vue 的事件處理方式都是使用 v-on:@ 來處理,那 React 呢?React 的事件稍微有一點點特別,但是如果你寫過 onclick 這種事件觸發的方式,那麼你會覺得 React 事件處理方式很熟悉

1
<a href="https://israynotarray.com/" onclick="sayHi(event)">點我</a>

上面這個 onclick 範例稱之為「Inline events」,通常會是 on+[事件名稱]="函式()",而實戰開發上我們也會盡可能避免使用 Inline events 的方式來綁定事件,原因是什麼就不細談了,因為這不是這一次主題要討論的範圍內。

拉回到 React 的事件處理。

為什麼要特別提到 「Inline events」 這件事情呢?主要原因是 React 事件處理寫法與與 「Inline events」 有高度的 87% 神似,讓我們看一下 React 的 Click 事件怎麼寫

1
<a href="https://israynotarray.com/" onClick={ sayHi }>點我</a>

雖然 Inline events 與 React 事件處理的方式有高達 87% 神似,但是 React 的撰寫方式則是 on+[事件名稱]={ 函式 },事件名稱首字會是大寫且採用 camelCase 方式。

所以我們簡單列一下 Inline events 與 React 事件處理的兩者差異

  • Inline events 採用全小寫形式,React 事件處理則是 camelCase
  • Inline events 傳入的是一個字串(String),React 事件處理傳入的是一個函式

React 事件修飾符?

這時候你可能會好奇了…

React 會跟 Vue 一樣擁有事件修飾符嗎?如果有的話,是不是應該這樣寫 onClick.prevent={ sayHi }

你真的非常聰明呢!恭喜你答案是…

沒有這個東西!

原因很簡單 React 本身寫起來就像是在寫純粹的 JavaScript,因此你必須明確的呼叫 preventDefault(); 才可以避免預設行為的觸發

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const App = () => {
const sayHi = (e) => {
e.preventDefault()
window.alert('Hello!');
}

return (
<div>
<a href="https://israynotarray.com/" onClick={ sayHi }>點我</a>
</div>
)
}

const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);
root.render(<App />);

這也是為什麼可以常常聽到人家說寫 React 彷彿在寫純粹的 JavaScript 一樣。

那麼這邊我也簡單列一下 React 常見的事件處理:

  • onClick
  • onChange
  • onSubmit
  • onKeyDown
  • onFocus
  • onBlur

請切記 React 的撰寫方式則是 on+[事件名稱]="{ 函式 }",絕對不是 on+[事件名稱]="名稱()" 這種!

單看文字上的描述其實是很難理解每一個事件處理的運作,因此後面我會針對每一個事件處理寫一個範例。

onClick

前面我們已經撰寫了無數次關於 onClick 事件的範例,儘管如此我們還是要再看一次 onClick 盡可能地去熟悉這種寫法,讓它深刻的刻畫在腦袋中

onClick 是一個很基本的點擊事件,當你點擊之後會觸發你所傳入的函式,如果你不傳入任何參數,而是單純的傳入一個函式名稱,那麼預設就會傳入一個 evnet (點擊事件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const App = () => {
const handler = (event) => {
event.preventDefault()
window.alert('Click!');
}

return (
<div>
<a href="https://israynotarray.com/" onClick={ handler }>點我</a>
</div>
)
}

const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);
root.render(<App />);

(對應的是 Vue @click 事件)

onChange

onChange 事件最常用於 inputtextareaselect 元素上,舉例來講,當我們選擇了 select 某個資料時,則會取得 option 內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const App = () => {
const handler = (event) => {
window.alert(`你選擇了:${event.target.value}`);
}

return (
<div>
<select onChange={ handler } name="location">
 <option value="Taipei">台北</option>
 <option value="Taoyuan">桃園</option>
 <option value="Hsinchu">新竹</option>
</select>
</div>
)
}

const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);
root.render(<App />);

(對應的是 Vue @Change 事件)

onSubmit

onSubmit 主要用於 form 表單上,而表單基本上有三劍客 Form、輸入欄位、Submit 按鈕

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const App = () => {
const handlerSubmit = (e) => {
e.preventDefault();
window.alert('submit');
}

return (
<div>
<form onSubmit={ handlerSubmit }>
<label htmlFor="account">帳號</label>
<input id="account" type="text" />
<button type="submit">送出</button>
</form>
</div>
)
}

const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);
root.render(<App />);

請注意 label 上的 for 屬性必須改寫成 htmlFor,否則會出現「Warning: Invalid DOM property for. Did you mean htmlFor?」這一段錯誤訊息,而這一個錯誤是因為 JSX 本身也是 JavaScript,因此剛剛好 for 會與 JavaScript 的保留字 for loop 有所衝突,因此要額外更改名稱。

(對應的是 Vue @Submit 事件)

onKeyDown

除了 onSubmitonChange 之外,另一個常見的監聽就是 onKeyDown ,如果你是在實作一個 ToDoList 之類的小東西,那麼 onKeyDown 就必定會很常使用,例如監聽目前按什麼按鍵

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const App = () => {
const handler = (e) => {
e.preventDefault();
window.alert(`你按下了${e.key} 按鍵,按鈕是 ${e.keyCode}`);
}

return (
<div>
<input type="text" onKeyDown={ handler } />
</div>
)
}

const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);
root.render(<App />);

(對應的是 Vue @keyup 事件)

onFocus

onFocus 使用場景大多常見於輸入匡,只要我們關注那個欄位就會觸發事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const App = () => {
const handlerFocus = () => {
window.alert('Focus');
}

return (
<div>
<input type="text" onFocus={ handlerFocus } />
</div>
)
}

const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);
root.render(<App />);

(對應的是 Vue @focus 事件)

onBlur

Foucs 是關注的話,那麼 Blur 就是離開關注的時候會觸發

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const App = () => {
const handlerBlur = (e) => {
window.alert('Blur');
}

return (
<div>
<input type="text" onBlur={ handlerBlur } />
</div>
)
}

const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);
root.render(<App />);

(對應的是 Vue @blur 事件)

那麼以上差不多就是常見的事件處理的部分。

後記

本文將會同步更新到我的部落格