延續前一篇用來練習傳遞React props做的成績填寫小程式。
前一篇的成績填寫小程式 有個惱人的問題,就是使用者只要一打開小程式就會立刻跟你要成績,感覺有點咄咄逼人。
為了修正這個小程式,目前構想是這樣的:
打開程式以後,要點選按鈕才會跳出成績填答的詢問視窗,並更新畫面上所顯示的成績。
因此這篇想了解React的事件處理,在按鈕上新增修正成績的事件來修正這個小程式。
React component 的事件處理跟JS DOM 處理事件的方式相當類似,基本上使用JSX語法處理事件只需要掌握幾個原則:
- camelCase語法
- 傳遞function,而非string,例如
<Component onClick={ eventHandler}>
,eventHandler是一個不帶參數的函式名稱。 - 傳遞帶有參數的function要用到callback技巧,例如
onClick={ ()=>eventHandler(1)}
,這裡用傳遞函式參數的技巧呼叫一個帶有引數1的函式(eventHandler)。 - 防止事件(event)預設行為必須使用
e.preventDefault()
而不能用return false
。
根據以上原則來做個按鈕更新一下這個小程式,要注意的是,因為還沒講到 state 的概念,所以這裡會重複使用到Student component:
首先移除原來用 prompt()
傳入成績的 <Student />
,因為這樣會在打開網頁時就直接詢問成績,另外做一個 <Edit />
的元件,這個元件會先給定 <Student chinese={0} math={0} english={0} />
避免畫面完全沒有顯示任何文字,並且加上一個可以修改成績的按鈕。
按鈕的作用在於等使用者按下以後,會重新渲染出用 prompt()
詢問成績的 <Student />
元件,接著就會跟前一篇出現一樣的效果,修改的程式碼如下。
function Edit(){
const updateScore = (e)=>{
e.preventDefault();
ReactDOM.render(
<Student
chinese={prompt("Enter your Chinese grade:")}
math={prompt("Enter your Math grade:")}
english={prompt("Enter your English grade:")}
/>,
e.target.parentNode.querySelector("main")
);
}
return (
<div>
<main>
<Student chinese={0} math={0} english={0} />
</main>
<button onClick={updateScore}>Click to Edit Scores</button>
</div>
)
}
ReactDOM.render(
<StrictMode>
<Edit/>
</StrictMode>,
document.getElementById("root")
);
一樣附上 Live Demo
做到這裡可以發現改個畫面上成績的值,必須得複製兩次 <Student>
傳遞不同引數來完成,感覺有點麻煩,幸好 React 提供可以操縱 state 的語法,可以幫忙改變 component內某些值的 狀態 。
狀態在這裡就是指希望把成績輕輕鬆鬆從 0 變成使用者輸入值的狀況,接下來介紹可以改變狀態的一種 Hook,useState
,但在此之前會簡短地說明Hooks是什麼,以及它和Component的關係。
其他筆記
- 文件特別說到 React 的事件是基於W3C Draft 所定義的 SyntheticEvent,跟原生事件多少有些不同,詳情可參考 SyntheticEvent。
References