2-7 與使用者互動 - React 中的事件處理
在上一個單元中我們已經完成整個計數器的畫面,並且把計數器建立成一個 React 元件,但是目前只有畫面還沒有實際的功能。在這個單元中將回學到如何在 React 中進行事件處理,包含在 JSX 中綁定 DOM 事件,以及在 React 元件中定義事件處理的方法。
#
在 React 元件中使用變數在前面的單元中,我們曾經提到如何把變數放到 JSX 中呈現,現在雖然我們已經把計數器包成了 React 元件,但它本質上還是一個回傳 JSX 的 JavaScript 函式,因此如果我們想要在 React 元件帶入變數的做法是一樣的。
現在我們先把上一個單元完成的 <Counter />
元件中的數字部分改成用變數來呈現,你可以 Fork 上一個單元的程式碼繼續開始。
在一個單元中,因為 <Counter />
元件是直接回傳一個 JSX,所以在箭頭函式中,我們可以直接在 =>
後面回傳 JSX 元件;但現在因為我們要在函式內加入變數,所以要改回最一般箭頭函式的寫法,也就是 () => {}
,這時候就可以在這個函式中加入計數器的變數,像是這樣:
把變數帶入 JSX 的方法一樣,只是現在我們把變數 count
宣告在 Counter
這個 component 裡面:
info
💡 在 JSX 中因為它本質上是 JavaScript,所以如果想在 JSX 內撰寫註解的話,可以把註解寫在 {}
裡面,像是這樣 {/* 這裡是註解 */}
。
#
在 React 元件中綁定事件監聽器為了讓計數器能夠運作,現在我們需要一個方法來改變 count
這個變數。先前使用原生的 JavaScript 時,是使用 addEventListener('click', ...)
的方法,在 React 元件中則是會透過 onClick
直接把事件綁定在 JSX 上面。例如,現在想要在「向上箭頭」的按鈕綁定點擊事件時,可以在 JSX 中這樣寫:
onClick={...}
中 {...}
內要放的就是點擊後要做什麼處理, 一般稱作事件處理器(event handlers),它會是一個函式。我們來試試看,當使用者點擊向上箭頭的時候,在 console
中顯示訊息,像是這樣:
這時候從瀏覽器的 console 視窗中,可以看到當點擊向上箭頭時會有訊息呈現,而向下箭頭因為還沒有註冊事件,因此點擊後不會有反應。
#
試著修改變數,看看畫面會不會改變接下來會很直覺的想說,既然現在已經可以監聽使用者的點擊事件,那要改變數字就沒問題了,只需要像先前原生 JavaScript 的寫法一樣,在使用者點擊畫面時,把 count + 1
就可以了吧!?
於是我們把 const count = 256
改成 let count = 256
讓 count
可以重新被賦值,在 onClick
的時候讓這個 count
變數的值加 1,像這樣:
但實際測試的結果你會發現和我們預期的卻不太一樣,你會發現,當我們點擊箭頭時,雖然在瀏覽器 console 顯示的 count
數字有持續增加,但是畫面的數字卻是變也不變!為什麼會這樣子呢?
#
為什麼畫面沒有改變一開始碰到這個問題會有些困惑,但了解原因之後並不難懂。因為雖然 count
的數字更新了,但 React 並不知道數字有更新,所以它不會去重新轉譯瀏覽器的畫面,這個感覺有點類似先前在我們使用原生 JavaScript 撰寫計數器時,雖然在使用者點擊按鍵後有把 count + 1
,但最後沒有使用 numberElement.textContent
把更新後的值重新給回網頁的情況。
當然,我們不能只是說說而已,要確定是不是真的因為 React 元件的畫面沒有更新(重新轉譯)才使得畫面上的數字沒有改變的話,我們可以在 JSX 中使用 {console.log('render')}
來看看,因為只要 React 有需要更新畫面的話,這個 JSX 就會被重新執行。因此,我們可以像這樣寫:
打開 console 視窗你應該會看到如下的訊息,一開始什麼都不做的時候出現了 "render",接著每點擊一次按鈕,就出現寫在事件處理器中的訊息:
這個意思表示,我們的畫面只有被轉譯了一次,即使之後 count
變數更新了,畫面也沒有跟著更新(重新轉譯)。那麼接下來的問題就是,要怎麼讓 React
知道,我們的數字改變了,並請它幫我們更新畫面呢?
在下一個單元中我們會使的到第一個 React Hook,讓 React 能夠知道我們的變數更新了,請 React 幫我們更新畫面。
#
換你了:在 React 元件中綁定事件現在,換你試著實際操作看看,在這裡我們使用的是點擊事件,因此綁定了 onClick
元素,但如同 HTML 一樣,我們還可以綁定各種其他的 DOM 事件,像是鍵盤的 onKeyPress
、onKeyUp
;表單的 onChange
、onInput
、onSubmit
等等。
唯一要稍微留意的是,這些事件名稱大多和 HTML 原生綁定事件的名稱相似,只是因為在 JSX 中 HTML 標籤的屬性慣例上是使用小寫駝峰來命名,因此原生的 onclick
在 JSX 中會變成 onClick
;onsubmit
則變成 onSubmit
等等。你可以在 React 官方文件的 SyntheticEvent(https://reactjs.org/docs/events.html)中找到幾乎所有要用的事件。
實作過程中如果有任何不清楚的地方,都可以到下方的連結查看原始碼,或透過 Github 說明頁點擊連結「在 React 元件中綁定事件」: