Handling Form Submission

接下來將取得表單資料,並模擬將表單資料送出的動作

在原生 browser 中,如果是位於 form 表單內 type="submit" 的 button,在點擊時都會觸發 form 上預設的 event submit,在 React 中,按照慣例會在前方加上 on (onSubmit)

1
2
3
4
5
6
7
8
9
10
11
// ExpenseForm.js
function ExpenseForm() {
const submitHandler = (event) => {};

return (
<form onSubmit={submitHandler}>
...
<button type="submit">Add Expense</button>
</form>
);
}

但原生的 sumbit event 會因為送出 request 而 reload browser,這不是我們期待的結果,所以需要透過一個 default event function event.preventDefault 來預防這件事發生

1
2
3
4
5
6
7
8
9
10
11
12
13
// ExpenseForm.js
function ExpenseForm() {
const submitHandler = (event) => {
event.preventDefault();
};

return (
<form onSubmit={submitHandler}>
...
<button type="submit">Add Expense</button>
</form>
);
}

接著我們暫時先將三筆表單資料特自透過 useState 來建立,並在 submit event 中組合成一個 object 送出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// ExpenseForm.js
function ExpenseForm() {
const [enteredTitle, setEnteredTitle] = useState("");
const [enteredAmount, setEnteredAmount] = useState("");
const [enteredDate, setEnteredDate] = useState("");

const submitHandler = (event) => {
event.preventDefault();

const expenseData = {
title: enteredTitle,
amount: enteredAmount,
date: new Date(enteredDate),
};

console.log(expenseData);
};

return (
<form onSubmit={submitHandler}>
...
<button type="submit">Add Expense</button>
</form>
);
}

Adding Two-Way Binding

到目前為止,我們都只是單方面的監聽使用者輸入的內容,但如果我們希望在點擊送出表單的按鈕 (Submit) 時,將所有欄位的資料清空,就需要用到 React 中一個很重要的觀念 - 雙向綁定 Two-Way Binding,以現有的範例延伸,我們只需要在 input 上加上屬性 value,並將 State 各自綁定上去,這一來就可以藉由改變 State 來改變 input 的內容了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/** @format */

import React, { useState } from "react";

import "./ExpenseForm.css";

const ExpenseForm = () => {
const [enteredTitle, setEnteredTitle] = useState("");
const [enteredAmount, setEnteredAmount] = useState("");
const [enteredDate, setEnteredDate] = useState("");

const titleChangeHandler = (event) => {
setEnteredTitle(event.target.value);
};

const amountChangeHandler = (event) => {
setEnteredAmount(event.target.value);
};

const dateChangeHandler = (event) => {
setEnteredDate(event.target.value);
};

const submitHandler = (event) => {
event.preventDefault();

setEnteredTitle('');
setEnteredAmount('');
setEnteredDate('');
};

return (
<form onSubmit={submitHandler}>
<div className="new-expense__controls">
<div className="new-expense__control">
<label>Title</label>
<input
type="text"
value={enteredTitle}
onChange={titleChangeHandler}
/>
</div>
<div className="new-expense__control">
<label>Amount</label>
<input
type="number"
min="0.01"
step="0.01"
value={enteredAmount}
onChange={amountChangeHandler}
/>
</div>
<div className="new-expense__control">
<label>Date</label>
<input
type="date"
min="2019-01-01"
max="2022-12-31"
value={enteredDate}
onChange={dateChangeHandler}
/>
</div>
</div>
<div className="new-expense__actions">
<button type="submit">Add Expense</button>
</div>
</form>
);
};

export default ExpenseForm;

資料參考

React - The Complete Guide (Incl Hooks, React Router, Redux)
Github