內建瀏覽器 <select>
元件 可讓您渲染帶有選項的下拉式選單。
<select>
<option value="someOption">Some option</option>
<option value="otherOption">Other option</option>
</select>
參考
<select>
要顯示下拉式選單,請渲染內建瀏覽器 <select>
元件。
<select>
<option value="someOption">Some option</option>
<option value="otherOption">Other option</option>
</select>
屬性
<select>
支援所有 通用元素屬性。
您可以透過傳遞 value
屬性來 建立受控的下拉式選單
value
:字串(或multiple={true}
的字串陣列)。控制選取哪個選項。每個值字串都必須與<select>
內巢狀的某個<option>
的value
相符。
當您傳遞 value
時,您也必須傳遞一個 onChange
事件處理函式來更新傳遞的值。
如果您的 <select>
是非受控的,您可以改為傳遞 defaultValue
屬性
defaultValue
:字串(或multiple={true}
的字串陣列)。指定 預設選取的選項。
以下 <select>
屬性與非受控和受控下拉式選單皆相關
autoComplete
:字串。指定其中一種可能的 自動完成行為。autoFocus
:一個布林值。如果設為true
,React 會在掛載時將焦點放在此元素上。children
:<select>
接受<option>
、<optgroup>
和<datalist>
組件作為子元素。您也可以傳遞您自己的組件,只要它們最終渲染成允許的組件之一即可。如果您傳遞最終渲染成<option>
標籤的組件,則您渲染的每個<option>
都必須具有value
屬性。disabled
:一個布林值。如果設為true
,則下拉式選單將無法互動,並會呈現暗淡的外觀。form
:一個字串。指定此下拉式選單所屬的<form>
的id
。如果省略,則為最接近的父表單。multiple
:一個布林值。如果設為true
,瀏覽器允許多選。name
:一個字串。指定此下拉式選單的名稱,該名稱會隨表單提交。onChange
:一個Event
事件處理函式。 受控下拉式選單必填。當使用者選擇不同的選項時立即觸發。行為類似瀏覽器的input
事件。onChangeCapture
:在 捕獲階段觸發的onChange
版本。onInput
:一個Event
事件處理函式。當使用者更改值時立即觸發。由於歷史原因,在 React 中習慣使用功能類似的onChange
來代替。onInputCapture
:在 捕獲階段觸發的onInput
版本。onInvalid
:一個Event
事件處理函式。如果輸入在表單提交時驗證失敗,則會觸發。與內建的invalid
事件不同,React 的onInvalid
事件會向上冒泡。onInvalidCapture
:在 捕獲階段觸發的onInvalid
版本。required
:一個布林值。如果設為true
,則必須提供值才能提交表單。size
:一個數字。對於multiple={true}
的下拉式選單,指定最初可見項目的首選數量。
注意事項
- 與 HTML 不同,將
selected
屬性傳遞給<option>
是不支援的。相反地,對於非受控下拉式選單,請使用<select defaultValue>
;對於受控下拉式選單,請使用<select value>
。 - 如果下拉式選單收到
value
屬性,它將被 視為受控的。 - 下拉式選單不能同時是受控的和非受控的。
- 下拉式選單在其生命週期中不能在受控或非受控之間切換。
- 每個受控下拉式選單都需要一個
onChange
事件處理程式,以同步更新其背後的值。
用法
顯示帶有選項的下拉式選單
渲染一個包含 <option>
元件列表的 <select>
以顯示下拉式選單。給每個 <option>
一個 value
,表示要與表單一起提交的數據。
export default function FruitPicker() { return ( <label> Pick a fruit: <select name="selectedFruit"> <option value="apple">Apple</option> <option value="banana">Banana</option> <option value="orange">Orange</option> </select> </label> ); }
提供下拉式選單的標籤
通常,您會將每個 <select>
放置在 <label>
標籤內。這會告訴瀏覽器此標籤與該下拉式選單相關聯。當使用者點擊標籤時,瀏覽器會自動將焦點放在下拉式選單上。這對於無障礙環境也很重要:當使用者將焦點放在下拉式選單上時,螢幕閱讀器會讀出標籤說明文字。
如果您無法將 <select>
嵌套到 <label>
中,請透過將相同的 ID 傳遞給 <select id>
和 <label htmlFor>
來關聯它們。為了避免一個元件的多個執行個體之間發生衝突,請使用 useId
產生這樣的 ID。
import { useId } from 'react'; export default function Form() { const vegetableSelectId = useId(); return ( <> <label> Pick a fruit: <select name="selectedFruit"> <option value="apple">Apple</option> <option value="banana">Banana</option> <option value="orange">Orange</option> </select> </label> <hr /> <label htmlFor={vegetableSelectId}> Pick a vegetable: </label> <select id={vegetableSelectId} name="selectedVegetable"> <option value="cucumber">Cucumber</option> <option value="corn">Corn</option> <option value="tomato">Tomato</option> </select> </> ); }
提供預設選取的選項
預設情況下,瀏覽器會選取列表中的第一個 <option>
。要預設選取不同的選項,請將該 <option>
的 value
作為 defaultValue
傳遞給 <select>
元素。
export default function FruitPicker() { return ( <label> Pick a fruit: <select name="selectedFruit" defaultValue="orange"> <option value="apple">Apple</option> <option value="banana">Banana</option> <option value="orange">Orange</option> </select> </label> ); }
export default function FruitPicker() { return ( <label> Pick some fruits: <select name="selectedFruit" defaultValue={['orange', 'banana']} multiple={true} > <option value="apple">Apple</option> <option value="banana">Banana</option> <option value="orange">Orange</option> </select> </label> ); }
提交表單時讀取下拉式選單的值
在您的下拉式選單周圍添加一個包含 <button type="submit">
的 <form>
。它將呼叫您的 <form onSubmit>
事件處理程式。預設情況下,瀏覽器會將表單數據發送到目前的 URL 並重新整理頁面。您可以透過呼叫 e.preventDefault()
來覆蓋該行為。使用 new FormData(e.target)
讀取表單數據。
export default function EditPost() { function handleSubmit(e) { // Prevent the browser from reloading the page e.preventDefault(); // Read the form data const form = e.target; const formData = new FormData(form); // You can pass formData as a fetch body directly: fetch('/some-api', { method: form.method, body: formData }); // You can generate a URL out of it, as the browser does by default: console.log(new URLSearchParams(formData).toString()); // You can work with it as a plain object. const formJson = Object.fromEntries(formData.entries()); console.log(formJson); // (!) This doesn't include multiple select values // Or you can get an array of name-value pairs. console.log([...formData.entries()]); } return ( <form method="post" onSubmit={handleSubmit}> <label> Pick your favorite fruit: <select name="selectedFruit" defaultValue="orange"> <option value="apple">Apple</option> <option value="banana">Banana</option> <option value="orange">Orange</option> </select> </label> <label> Pick all your favorite vegetables: <select name="selectedVegetables" multiple={true} defaultValue={['corn', 'tomato']} > <option value="cucumber">Cucumber</option> <option value="corn">Corn</option> <option value="tomato">Tomato</option> </select> </label> <hr /> <button type="reset">Reset</button> <button type="submit">Submit</button> </form> ); }
使用狀態變數控制下拉式選單
像`
**要渲染一個*受控的*下拉式選單,請傳遞`value`屬性給它。** React 將會強制下拉式選單永遠保持您傳遞的`value`。通常,您會透過宣告一個狀態變數來控制下拉式選單:
function FruitPicker() {
const [selectedFruit, setSelectedFruit] = useState('orange'); // Declare a state variable...
// ...
return (
<select
value={selectedFruit} // ...force the select's value to match the state variable...
onChange={e => setSelectedFruit(e.target.value)} // ... and update the state variable on any change!
>
<option value="apple">Apple</option>
<option value="banana">Banana</option>
<option value="orange">Orange</option>
</select>
);
}
如果您想要在每次選取時重新渲染 UI 的某些部分,這會很有用。
import { useState } from 'react'; export default function FruitPicker() { const [selectedFruit, setSelectedFruit] = useState('orange'); const [selectedVegs, setSelectedVegs] = useState(['corn', 'tomato']); return ( <> <label> Pick a fruit: <select value={selectedFruit} onChange={e => setSelectedFruit(e.target.value)} > <option value="apple">Apple</option> <option value="banana">Banana</option> <option value="orange">Orange</option> </select> </label> <hr /> <label> Pick all your favorite vegetables: <select multiple={true} value={selectedVegs} onChange={e => { const options = [...e.target.selectedOptions]; const values = options.map(option => option.value); setSelectedVegs(values); }} > <option value="cucumber">Cucumber</option> <option value="corn">Corn</option> <option value="tomato">Tomato</option> </select> </label> <hr /> <p>Your favorite fruit: {selectedFruit}</p> <p>Your favorite vegetables: {selectedVegs.join(', ')}</p> </> ); }