iT邦幫忙

2022 iThome 鐵人賽

DAY 5
1
Modern Web

終究都要學 React 何不現在學呢?系列 第 5

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

  • 分享至 

  • xImage
  •  

前言

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

Vue 事件處理

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

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

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

CodePen 連結

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

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

CodePen 連結

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

Vue 事件修飾符

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

https://ithelp.ithome.com.tw/upload/images/20220918/20119486JxXzVBWovf.png

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

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

CodePen 連結

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

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

React 事件處理

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

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

CodePen 連結

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

拉回到 React 的事件處理。

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

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

CodePen 連結

雖然 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(); 才可以避免預設行為的觸發

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 />);

CodePen 連結

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

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

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

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

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

onClick

前面我們已經撰寫了無數次關於 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 />);

CodePen 連結

(對應的是 Vue @click 事件)

onChange

onChange 事件最常用於 inputtextareaselect 元素上,舉例來講,當我們選擇了 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 />);

CodePen 連結

(對應的是 Vue @Change 事件)

onSubmit

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 />);

CodePen 連結

請注意 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 就必定會很常使用,例如監聽目前按什麼按鍵

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 />);

CodePen 連結

(對應的是 Vue @keyup 事件)

onFocus

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 />);

CodePen 連結

(對應的是 Vue @focus 事件)

onBlur

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 />);

CodePen 連結

(對應的是 Vue @blur 事件)

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

後記

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


上一篇
終究都要學 React 何不現在學呢? - React 基礎 - JSX - (4)
下一篇
終究都要學 React 何不現在學呢? - React 基礎 - 元件 - (6)
系列文
終究都要學 React 何不現在學呢?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

1
一顆蘋果熊
iT邦新手 5 級 ‧ 2022-09-19 13:48:29

太過分了!騙人進部落格!!怒按讚!!

Ray iT邦研究生 4 級 ‧ 2022-09-19 14:25:26 檢舉

給你個讚

1
吠吠
iT邦新手 3 級 ‧ 2022-09-23 16:15:47

有兩者做比較真的可以比較快讓原本 vue 轉 react 的新手上手耶~

Ray iT邦研究生 4 級 ‧ 2022-09-23 21:52:36 檢舉

一看就上手

我要留言

立即登入留言