接著來聊聊 React 的事件處理,畢竟事件處理這件事情我們在開發上是非常常見的。
一開始我們先來快速聊一下 Vue 的部分。
Vue 本身是採用 v-on:事件名稱="函式"
的概念撰寫,以點擊事件(click
)並觸發一個打招呼函式(sayHi
)當作舉例
<a href="https://israynotarray.com/" v-on:click="sayHi">點我</a>
但是實戰上其實我們很少寫 v-on:
大多都是使用事件修飾符 「@
」來取代 v-on:
<a href="https://israynotarray.com/" @click="sayHi">點我</a>
而上方就是我們最基本使用 Vue 的事件處理方式。
上面的範例你會發現當你點了之後會先跳出警告視窗,之後畫面就被個轉到我的部落格 (其實這是一個計畫通概念)
其實這個問題是連結本身有預設行為的關係,也就是重新轉址導向至 href
網址,如同使用表單送出時的 action
路徑相同,如果要解決這個問題的話,我們就要使用 Vue 的「事件修飾符」,那麼事件修飾符非常多,所以這邊就只介紹一個也就是 .prevent
,只要你在 @click
後方補個 .prevent
就可以解決重新轉址導向的問題
<a href="https://israynotarray.com/" @click.prevent="sayHi">點我</a>
透過事件修飾符就可以避免我們點擊連結就會跳轉的問題了。
前面這邊快速回顧與了解 Vue 的事件處理、事件修飾符後,React 呢?React 又是如何呢?所以我們接著下去。
前面我們快速了回顧 Vue 的事件處理方式都是使用 v-on:
與 @
來處理,那 React 呢?React 的事件稍微有一點點特別,但是如果你寫過 onclick
這種事件觸發的方式,那麼你會覺得 React 事件處理方式很熟悉
<a href="https://israynotarray.com/" onclick="sayHi(event)">點我</a>
上面這個 onclick
範例稱之為「Inline events」,通常會是 on+[事件名稱]="函式()"
,而實戰開發上我們也會盡可能避免使用 Inline events 的方式來綁定事件,原因是什麼就不細談了,因為這不是這一次主題要討論的範圍內。
拉回到 React 的事件處理。
為什麼要特別提到 「Inline events」 這件事情呢?主要原因是 React 事件處理寫法與與 「Inline events」 有高度的 87% 神似,讓我們看一下 React 的 Click 事件怎麼寫
<a href="https://israynotarray.com/" onClick={ sayHi }>點我</a>
雖然 Inline events 與 React 事件處理的方式有高達 87% 神似,但是 React 的撰寫方式則是 on+[事件名稱]={ 函式 }
,事件名稱首字會是大寫且採用 camelCase 方式。
所以我們簡單列一下 Inline events 與 React 事件處理的兩者差異
這時候你可能會好奇了...
React 會跟 Vue 一樣擁有事件修飾符嗎?如果有的話,是不是應該這樣寫 onClick.prevent={ sayHi }
?
你真的非常聰明呢!恭喜你答案是...
沒有這個東西!
原因很簡單 React 本身寫起來就像是在寫純粹的 JavaScript,因此你必須明確的呼叫 preventDefault();
才可以避免預設行為的觸發
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
是一個很基本的點擊事件,當你點擊之後會觸發你所傳入的函式,如果你不傳入任何參數,而是單純的傳入一個函式名稱,那麼預設就會傳入一個 evnet
(點擊事件)
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
事件最常用於 input
、textarea
及 select
元素上,舉例來講,當我們選擇了 select
某個資料時,則會取得 option
內容
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
主要用於 form
表單上,而表單基本上有三劍客 Form
、輸入欄位、Submit
按鈕
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
事件)
除了 onSubmit
、onChange
之外,另一個常見的監聽就是 onKeyDown
,如果你是在實作一個 ToDoList 之類的小東西,那麼 onKeyDown
就必定會很常使用,例如監聽目前按什麼按鍵
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
使用場景大多常見於輸入匡,只要我們關注那個欄位就會觸發事件
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
事件)
Foucs 是關注的話,那麼 Blur 就是離開關注的時候會觸發
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
事件)
那麼以上差不多就是常見的事件處理的部分。
本文將會同步更新到我的部落格