React 官方文件目前已結束第三章,進入最後一個章節的學習前,最後幾天的鐵人賽以實作的練習來複習所學習過的內容吧。今天要來練習輸入授權碼的表單製作。要讓使用者鍵入數字,並比對數字是否正確,正確或錯誤都顯示出相對應的訊息。
目前有的程式碼如下:
import React from "react";
const CORRECT_CODE = "123456";
function TwoFactor() {
return (
<>
<label htmlFor="auth-code">Enter authorization code:</label>
<div className="row">
<input id="auth-code" type="text" required={true} maxLength={6} />
<button>Validate</button>
</div>
</>
);
}
export default TwoFactor;
畫面看起來會是這樣:
CORRECT_CODE
先在 TwoFactor funciton 當中加上useState
用來管理狀態和控制渲染。
const [code, setCode] = React.useState("");
<input
id="auth-code"
type="text"
required={true}
maxLength={6}
value={code}
onChange={(event) => {
setCode(event.target.value);
}}
/>
第二步,在input
元素添加value
和onChange
屬性並與剛剛編寫的狀態變數資料綁定。input
元素使用了 value
屬性,將它的值綁定到了狀態變數 code
。同時,onChange
屬性被設置為一個函式,當使用者輸入內容時,這個函數將被調用,並將新的輸入值設置為 code
的狀態,這樣就實現了資料的雙向綁定。
接著要處理的是比對使用者鍵入的值的比對觸發。我們需要在TwoFactor
內部創建一個 function 來處理。
function handleSubmit() {
const isCorrect = code === CORRECT_CODE;
window.alert(isCorrect ? "Correct!" : "Incorrect!");
}
先將使用者鍵入值code
與CORRECT_CODE
正確的情況儲存至變數中,並當isCorrect
為真時,提示出Correct!
正確訊息,反之當不正確時則顯示Incorrect!
的訊息。
接著將剛剛創建的 function 綁定到元素上。直覺上會想綁定在button
上,像這樣:
<button onClick={handleSubmit}>Validate</button>
但如果考量到使用者不會是只有點擊,也有可能是以鍵盤 enter 鍵來提交表單的情況,我們可以使用form
元素。把容器的<></>
變更為<form></form>
元素即可。 這時當我們在 input 元素內輸入數字,並使用 enter 鍵來提出,即會看到這樣子的結果:
這樣子就代表我們的表單正常運作了。
當然我們也可以將事件綁定在<form>
元素上,像這樣:
<form onSubmit={handleSubmit}>
這樣就大致完成使用者驗證表單的製作了。
但當我們關閉訊息提醒後,會發現頁面刷新了,我們可以透過下一個步驟來避免這個事情。
在handleSubmit
function 當中追加避免預設的程式碼:
event.preventDefault();
當事件被觸發時,通常會伴隨著一些預設的行為。例如,當在表單中按下「提交」按鈕時,瀏覽器會嘗試向伺服器發送表單數據,這是表單的預設行為。透過event.preventDefault()
可以防止表單在提交時刷新頁面。
這樣即完成一個基礎表單驗證的功能。雖然我們在預想情況時是以比對「正確」、「不正確」來設想的,也可能會出現以下的情況,譬如使用者「尚未未輸入即提交」、「數字長度不符合」的情況。
目前的程式碼已經有設定required={true}
所以當使用者沒有輸入即提交時會出現這樣子的畫面:
這邊的訊息是瀏覽器預設的內容。
在原始的程式碼上已經設定好使用者可鍵入的最長內容,maxLength={6}
,所以使用者沒有辦法鍵入超過 6 個以上的數字。但若數字太短該如何提醒使用者呢?
(1) 另外創建 error message 的狀態變數:
const [errorMessage, setErrorMessage] = React.useState("");
(2) 在 Input 元素的 onChange 屬性上追加 setErrorMessage 的設定:
<input
id="auth-code"
type="text"
required={true}
maxLength={6}
value={code}
onChange={(event) => {
setCode(event.target.value);
setErrorMessage(""); //當使用者在打字時清空訊息
}}
/>
這邊的設定是確保使用者在打字時 Error Message 的內容會被清空。
(3) 編寫訊息出現的邏輯:
function handleSubmit(event) {
event.preventDefault();
if (code.length < 6) {
setErrorMessage("Code must be at least 6 characters long.");
} else {
const isCorrect = code === CORRECT_CODE;
window.alert(isCorrect ? "Correct!" : "Incorrect");
}
}
我們在handleSubmit
當中添加了檢查輸入內容長度的邏輯,這樣就完成了提醒使用者的設定。譬如當鍵入「12」二個數值並提交時,跳出訊息通知使用者,最短應該要有 6 位數,也能看見以下的畫面:
在檢查數字長度是否太短或太長時,這邊使用的方法是「先提交再通知」,若是想改變使用者體驗讓使用者同步輸入時便檢查的話也可以另外寫一個 function 來處理使用者輸入的檢查邏輯。這個 function 可以在 onChange
事件中呼叫,並且根據使用者的輸入來更新錯誤訊息的狀態。這種做法可以讓使用者在輸入時「即時看到錯誤訊息」,而不是等到提交表單時才看到。
雖然這樣子的做法可能可以在使用者尚未按出提交鍵就獲得通知提醒,並可以一次就成功輸入。但當使用者才剛開始輸入第一個數字時「1」提醒就馬上跳出來個人覺得還是壓力滿大的。
以上是考量到基礎的一些情境所需做的補充練習,實際表單也可能會遇到其他情境的問題需要考量如「多次驗證錯誤」、「輸入的不是數字」等的情況,需要再針對不同情況去處理。