内置浏览器 <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> ); }
使用状态变量控制选择框
像 `<select />
` 这样的选择框是 *不受控的*。即使您 传递了初始选定值(例如 `<select defaultValue="orange" />
`),您的 JSX 也只指定了初始值,而不是现在的值。
要渲染 *受控* 选择框,请将 `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> </> ); }