在 React 中,處理表單是常見的事情,通常使用onChange
事件處理器來去做資料的更新。
表單可能會有多種欄位,會將每個欄位拆開來介紹,以下分別為各種類型 input
、select
、 Textarea
、radio
、checkbox
的欄位應用。
input
元素通常用於單行文字的輸入。
import React, { useState } from 'react';
const InputExample = () => {
const [inputValue, setInputValue] = useState('');
const handleChange = (event) => {
setInputValue(event.target.value);
};
return (
<div>
<label>
Name:
<input type="text" value={inputValue} onChange={handleChange} />
</label>
<p>Current Input: {inputValue}</p>
</div>
);
};
export default InputExample;
onChange
事件:當使用者在 input
元素中輸入文字時,onChange
事件會被觸發。handleChange
會將事件對象(event
)傳入函式,event.target.value
能取得當前的輸入值,並更新狀態 inputValue
。setInputValue
更新狀態後,React 會重新渲染組件,顯示最新的 inputValue
。select
元素用於選擇下拉式選單中的一個選項。
import React, { useState } from 'react';
const SelectExample = () => {
const [selectedValue, setSelectedValue] = useState('apple');
const handleChange = (event) => {
setSelectedValue(event.target.value);
};
return (
<div>
<label>
Pick your favorite fruit:
<select value={selectedValue} onChange={handleChange}>
<option value="apple">Apple</option>
<option value="banana">Banana</option>
<option value="orange">Orange</option>
</select>
</label>
<p>Selected Fruit: {selectedValue}</p>
</div>
);
};
export default SelectExample;
onChange
事件:當使用者選擇一個不同的選項時,onChange
事件會被觸發。事件處理器 handleChange
會獲取新的選擇值並更新狀態 selectedValue
。setSelectedValue
更新狀態後,React 會重新渲染組件,顯示最新的選擇值。textarea
元素用於多行文本的輸入。這裡的範例展示如何使用 onChange
事件來更新 textarea
的內容。
import React, { useState } from 'react';
const TextareaExample = () => {
const [textValue, setTextValue] = useState('');
const handleChange = (event) => {
setTextValue(event.target.value);
};
return (
<div>
<label>
Comments:
<textarea value={textValue} onChange={handleChange} />
</label>
<p>Current Text: {textValue}</p>
</div>
);
};
export default TextareaExample;
onChange
事件:當使用者在 textarea
元素中輸入或刪除文本時,onChange
事件會被觸發。事件處理器 handleChange
會更新 textValue
狀態。setTextValue
更新狀態後,React 會重新渲染組件,顯示最新的文本內容。checkbox
元素為選中或未選中 (true , false )。以下範例展示如何使用 onChange
事件來更新 checkbox
的選中狀態。
import React, { useState } from 'react';
const CheckboxExample = () => {
const [isChecked, setIsChecked] = useState(false);
const handleChange = (event) => {
setIsChecked(event.target.checked);
};
return (
<div>
<label>
Accept Terms:
<input type="checkbox" checked={isChecked} onChange={handleChange} />
</label>
<p>Is Checked: {isChecked ? 'Yes' : 'No'}</p>
</div>
);
};
export default CheckboxExample;
onChange
事件:當使用者點擊 checkbox
元素時,onChange
事件會被觸發。事件處理器 handleChange
更新 isChecked
狀態,表示選中狀態。setIsChecked
更新狀態後,React 會重新渲染組件,顯示當前的選中狀態。radio
元素用於單一選擇。在這個範例中,我們展示如何處理 radio
元素的選中狀態。
import React, { useState } from 'react';
const RadioExample = () => {
const [selectedOption, setSelectedOption] = useState('option1');
const handleChange = (event) => {
setSelectedOption(event.target.value);
};
return (
<div>
<label>
Option 1:
<input
type="radio"
value="option1"
checked={selectedOption === 'option1'}
onChange={handleChange}
/>
</label>
<label>
Option 2:
<input
type="radio"
value="option2"
checked={selectedOption === 'option2'}
onChange={handleChange}
/>
</label>
<p>Selected Option: {selectedOption}</p>
</div>
);
};
export default RadioExample;
onChange
事件:當使用者選擇一個 radio
選項時,onChange
事件會被觸發。事件處理器 handleChange
獲取所選的值並更新 selectedOption
狀態。setSelectedOption
更新狀態後,React 會重新渲染組件,顯示當前選中的選項。常見的表單種類狀況,通常都是上述元素的組合,將上述的元素整理在表單範例中,並將每個的onChange
事件做整合性的處理,請觀看下方的範例:
import React, { useState } from 'react';
import './App.css';
const FormExample = () => {
// 狀態管理
const [formData, setFormData] = useState({
name: '',
favoriteFruit: 'apple',
comments: '',
gender: 'male',
isAgreed: false,
selectedHobbies: [], // 用來存放勾選的興趣
})
// 處理所有表單元素的變更
const handleChange = event => {
const {name, value, type, checked} = event.target
if (type === 'checkbox' && name === 'selectedHobbies') {
// 處理多個 checkbox 狀況
const updatedHobbies = checked
? [...formData.selectedHobbies, value] // 若勾選,則加入陣列
: formData.selectedHobbies.filter(hobby => hobby !== value) // 若取消勾選,則移除該選項
setFormData({
...formData,
selectedHobbies: updatedHobbies,
})
} else {
setFormData({
...formData,
[name]: type === 'checkbox' ? checked : value,
})
}
}
// 處理表單提交(這裡只是防止預設提交行為)
const handleSubmit = event => {
event.preventDefault()
console.log(formData)
alert('Form submitted! Check the console for details.')
}
return (
<div>
<h1>React 表單範例</h1>
<form onSubmit={handleSubmit}>
{/* Input 範例 */}
<div>
<label>
Name:
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
/>
</label>
</div>
{/* Select 範例 */}
<div>
<label>
Favorite Fruit:
<select
name="favoriteFruit"
value={formData.favoriteFruit}
onChange={handleChange}>
<option value="apple">Apple</option>
<option value="banana">Banana</option>
<option value="orange">Orange</option>
</select>
</label>
</div>
{/* Textarea 範例 */}
<div>
<label>
Comments:
<textarea
name="comments"
value={formData.comments}
onChange={handleChange}
/>
</label>
</div>
{/* Radio 範例 */}
<div>
<label>
Gender:
<label>
<input
type="radio"
name="gender"
value="male"
checked={formData.gender === 'male'}
onChange={handleChange}
/>
Male
</label>
<label>
<input
type="radio"
name="gender"
value="female"
checked={formData.gender === 'female'}
onChange={handleChange}
/>
Female
</label>
</label>
</div>
{/* 多個 Checkbox 範例 */}
<div>
<label>Hobbies:</label>
<label>
<input
type="checkbox"
name="selectedHobbies"
value="reading"
checked={formData.selectedHobbies.includes('reading')}
onChange={handleChange}
/>
Reading
</label>
<label>
<input
type="checkbox"
name="selectedHobbies"
value="traveling"
checked={formData.selectedHobbies.includes('traveling')}
onChange={handleChange}
/>
Traveling
</label>
<label>
<input
type="checkbox"
name="selectedHobbies"
value="cooking"
checked={formData.selectedHobbies.includes('cooking')}
onChange={handleChange}
/>
Cooking
</label>
</div>
{/* Checkbox 範例 */}
<div>
<label>
Agree to Terms:
<input
type="checkbox"
name="isAgreed"
checked={formData.isAgreed}
onChange={handleChange}
/>
</label>
</div>
{/* 提交表單按鈕 */}
<button type="submit">Submit</button>
</form>
{/* 顯示當前表單資料 */}
<div className='container'>
<h2>Form Data Preview:</h2>
<p>Name: {formData.name}</p>
<p>Favorite Fruit: {formData.favoriteFruit}</p>
<p>Comments: {formData.comments}</p>
<p>Gender: {formData.gender}</p>
<p>Hobbies: {formData.selectedHobbies.join(', ') || 'None'}</p>
<p>Agreed to Terms: {formData.isAgreed ? 'Yes' : 'No'}</p>
</div>
</div>
)
}
export default FormExample;
讓這些表單看起來比較美觀,增加CSS樣式的呈現。
CSS
/* FormExample.css */
/* 整體表單樣式 */
form {
max-width: 500px;
margin: 0 auto;
padding: 20px;
background-color: #f9f9f9;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
/* 表單標籤樣式 */
label {
display: block;
font-weight: bold;
margin-bottom: 8px;
}
/* 輸入框、選擇框、文本區域的樣式 */
input[type="text"],
select,
textarea {
width: 100%;
padding: 10px;
margin-bottom: 20px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
font-size: 16px;
}
/* 單選按鈕和複選框的樣式 */
input[type="radio"],
input[type="checkbox"] {
margin-right: 8px;
}
/* 單選按鈕與複選框的標籤樣式 */
label > label {
font-weight: normal;
margin-right: 15px;
}
/* 提交按鈕樣式 */
button[type="submit"] {
width: 100%;
padding: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
font-size: 18px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button[type="submit"]:hover {
background-color: #45a049;
}
/* 表單預覽樣式 */
h2 {
text-align: center;
margin-top: 30px;
}
p {
font-size: 16px;
margin: 5px 0;
}
表單範例所呈現的樣子如下: