内置浏览器 <select> 组件 允许你渲染带有选项的选择框。

¥The built-in browser <select> component lets you render a select box with options.

<select>
<option value="someOption">Some option</option>
<option value="otherOption">Other option</option>
</select>

参考

¥Reference

<select>

要显示选择框,请渲染 内置浏览器 <select> 组件。

¥To display a select box, render the built-in browser <select> component.

<select>
<option value="someOption">Some option</option>
<option value="otherOption">Other option</option>
</select>

请参阅下面的更多示例。

¥See more examples below.

属性

¥Props

<select> 支持所有 普通元素属性。

¥<select> supports all common element props.

你可以通过传递 value 属性来 控制选择框

¥You can make a select box controlled by passing a value prop:

  • value:字符串(或 multiple={true} 的字符串数组)。控制选择哪个选项。每个值字符串都匹配 <select> 中嵌套的某些 <option>value

    ¥value: A string (or an array of strings for multiple={true}). Controls which option is selected. Every value string match the value of some <option> nested inside the <select>.

当你传递 value 时,你还必须传递一个更新传递值的 onChange 处理程序。

¥When you pass value, you must also pass an onChange handler that updates the passed value.

如果你的 <select> 不受控制,你可以传递 defaultValue 属性:

¥If your <select> is uncontrolled, you may pass the defaultValue prop instead:

这些 <select> 属性与不受控制和受控制的选择框相关:

¥These <select> props are relevant both for uncontrolled and controlled select boxes:

  • autoComplete:一个字符串。指定可能的 自动补齐行为。 之一

    ¥autoComplete: A string. Specifies one of the possible autocomplete behaviors.

  • autoFocus:一个布尔值。如果是 true,React 会将元素集中在挂载上。

    ¥autoFocus: A boolean. If true, React will focus the element on mount.

  • children<select> 接受 <option><optgroup><datalist> 组件作为子级。你也可以传递自己的组件,只要它们最终渲染允许的组件之一。如果你传递自己的最终渲染 <option> 标签的组件,那么你渲染的每个 <option> 都必须有一个 value

    ¥children: <select> accepts <option>, <optgroup>, and <datalist> components as children. You can also pass your own components as long as they eventually render one of the allowed components. If you pass your own components that eventually render <option> tags, each <option> you render must have a value.

  • disabled:一个布尔值。如果是 true,选择框将不会是交互式的,并且会显示为灰色。

    ¥disabled: A boolean. If true, the select box will not be interactive and will appear dimmed.

  • form:一个字符串。指定此选择框所属的 <form>id。如果省略,它是最接近的父表单。

    ¥form: A string. Specifies the id of the <form> this select box belongs to. If omitted, it’s the closest parent form.

  • multiple:一个布尔值。如果 true,浏览器允许 多项选择。

    ¥multiple: A boolean. If true, the browser allows multiple selection.

  • name:一个字符串。指定此选择框的名称 与表格一起提交。

    ¥name: A string. Specifies the name for this select box that’s submitted with the form.

  • onChange:一个 Event 处理程序 函数。控制选择框。 需要当用户选择不同的选项时立即触发。行为类似于浏览器 input 事件。

    ¥onChange: An Event handler function. Required for controlled select boxes. Fires immediately when the user picks a different option. Behaves like the browser input event.

  • onChangeCapture:在 捕获阶段。 中触发的 onChange 版本

    ¥onChangeCapture: A version of onChange that fires in the capture phase.

  • onInput:一个 Event 处理程序 函数。当用户更改值时立即触发。由于历史原因,在 React 中惯用的是使用 onChange,它的工作方式类似。

    ¥onInput: An Event handler function. Fires immediately when the value is changed by the user. For historical reasons, in React it is idiomatic to use onChange instead which works similarly.

  • onInputCapture:在 捕获阶段。 中触发的 onInput 版本

    ¥onInputCapture: A version of onInput that fires in the capture phase.

  • onInvalid:一个 Event 处理程序 函数。如果输入在表单提交时验证失败,则触发。与内置的 invalid 事件不同,React onInvalid 事件冒泡。

    ¥onInvalid: An Event handler function. Fires if an input fails validation on form submit. Unlike the built-in invalid event, the React onInvalid event bubbles.

  • onInvalidCapture:在 捕获阶段。 中触发的 onInvalid 版本

    ¥onInvalidCapture: A version of onInvalid that fires in the capture phase.

  • required:一个布尔值。如果是 true,则必须提供该值以便提交表单。

    ¥required: A boolean. If true, the value must be provided for the form to submit.

  • size:一个号码。对于 multiple={true} 选择,指定最初可见项目的首选数量。

    ¥size: A number. For multiple={true} selects, specifies the preferred number of initially visible items.

注意事项

¥Caveats

  • 与 HTML 不同,不支持将 selected 属性传递给 <option>。而是,对不受控制的选择框使用 <select defaultValue>,对受控的选择框使用 <select value>

    ¥Unlike in HTML, passing a selected attribute to <option> is not supported. Instead, use <select defaultValue> for uncontrolled select boxes and <select value> for controlled select boxes.

  • 如果选择框收到 value 属性,它将是 作为控制处理。

    ¥If a select box receives a value prop, it will be treated as controlled.

  • 选择框不能同时受控和不受控。

    ¥A select box can’t be both controlled and uncontrolled at the same time.

  • 选择框在其生命周期内无法在受控或不受控之间切换。

    ¥A select box cannot switch between being controlled or uncontrolled over its lifetime.

  • 每个受控的选择框都需要一个 onChange 事件处理程序来同步更新其支持值。

    ¥Every controlled select box needs an onChange event handler that synchronously updates its backing value.


用法

¥Usage

显示带有选项的选择框

¥Displaying a select box with options

渲染一个 <select>,其中包含一个 <option> 组件列表,以显示一个选择框。给每个 <option> 一个 value,代表要随表单提交的数据。

¥Render a <select> with a list of <option> components inside to display a select box. Give each <option> a value representing the data to be submitted with the form.

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>
  );
}


为选择框提供标签

¥Providing a label for a select box

通常,你会将每个 <select> 放在 <label> 标签中。这告诉浏览器这个标签与那个选择框相关联。当用户点击标签时,浏览器会自动聚焦选择框。它对于可访问性也很重要:当用户聚焦选择框时,屏幕阅读器将宣布标签标题。

¥Typically, you will place every <select> inside a <label> tag. This tells the browser that this label is associated with that select box. When the user clicks the label, the browser will automatically focus the select box. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the select box.

如果不能将 <select> 嵌套到 <label> 中,通过将相同的 ID 传递给 <select id><label htmlFor> 来关联它们 为了避免一个组件的多个实例之间的冲突,使用 useId 生成这样的 ID

¥If you can’t nest <select> into a <label>, associate them by passing the same ID to <select id> and <label htmlFor>. To avoid conflicts between multiple instances of one component, generate such an ID with useId.

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>
    </>
  );
}


提供最初选择的选项

¥Providing an initially selected option

默认情况下,浏览器会选择列表中的第一个 <option>。要默认选择不同的选项,请将 <option>value 作为 defaultValue 传递给 <select> 元素。

¥By default, the browser will select the first <option> in the list. To select a different option by default, pass that <option>’s value as the defaultValue to the <select> element.

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>
  );
}

易犯错误

与 HTML 不同,不支持将 selected 属性传递给单个 <option>

¥Unlike in HTML, passing a selected attribute to an individual <option> is not supported.


启用多选

¥Enabling multiple selection

multiple={true} 传递给 <select> 让用户选择多个选项。在这种情况下,如果你还指定 defaultValue 来选择最初选择的选项,则它必须是一个数组。

¥Pass multiple={true} to the <select> to let the user select multiple options. In that case, if you also specify defaultValue to choose the initially selected options, it must be an array.

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>
  );
}


提交表单时读取选择框的值

¥Reading the select box value when submitting a form

在你的选择框周围添加一个 <form>,里面有一个 <button type="submit">。它将调用你的 <form onSubmit> 事件处理程序。默认情况下,浏览器会将表单数据发送到当前 URL 并刷新页面。你可以通过调用 e.preventDefault() 来覆盖该行为。使用 new FormData(e.target) 读取表单数据。

¥Add a <form> around your select box with a <button type="submit"> inside. It will call your <form onSubmit> event handler. By default, the browser will send the form data to the current URL and refresh the page. You can override that behavior by calling e.preventDefault(). Read the form data with 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> 一个 name,例如 <select name="selectedFruit" />。你指定的 name 将用作表单数据中的键,例如 { selectedFruit: "orange" }

¥Give a name to your <select>, for example <select name="selectedFruit" />. The name you specified will be used as a key in the form data, for example { selectedFruit: "orange" }.

如果你使用 <select multiple={true}>,你将从表单中读取的 FormData 会将每个选定值包含为单独的名称-值对。仔细查看上面示例中的控制台日志。

¥If you use <select multiple={true}>, the FormData you’ll read from the form will include each selected value as a separate name-value pair. Look closely at the console logs in the example above.

易犯错误

默认情况下,<form> 中的任何 <button> 都会提交它。这可能令人惊讶!如果你有自己的自定义 Button React 组件,请考虑返回 <button type="button"> 而不是 <button>。然后,明确地说,将 <button type="submit"> 用于应该提交表单的按钮。

¥By default, any <button> inside a <form> will submit it. This can be surprising! If you have your own custom Button React component, consider returning <button type="button"> instead of <button>. Then, to be explicit, use <button type="submit"> for buttons that are supposed to submit the form.


使用状态变量控制选择框

¥Controlling a select box with a state variable

<select /> 这样的选择框是不受控制的。即使你 传递最初选择的值 喜欢 <select defaultValue="orange" />,你的 JSX 也只是指定了初始值,而不是现在的值。

¥A select box like <select /> is uncontrolled. Even if you pass an initially selected value like <select defaultValue="orange" />, your JSX only specifies the initial value, not the value right now.

要渲染受控选择框,请将 value 属性传递给它。React 将强制选择框始终包含你传递的 value。通常,你将通过声明 状态变量 来控制选择框

¥To render a controlled select box, pass the value prop to it. React will force the select box to always have the value you passed. Typically, you will control a select box by declaring a state variable:

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 的某些部分以响应每个选择,这将很有用。

¥This is useful if you want to re-render some part of the UI in response to every selection.

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>
    </>
  );
}

易犯错误

如果你通过了 value 而没有通过 onChange,那么你将无法选择一个选项。当你通过将一些 value 传递给它来控制选择框时,你强制它始终具有你传递的值。因此,如果你将状态变量作为 value 传递,但忘记在 onChange 事件处理程序期间同步更新该状态变量,React 将在每次击键后将选择框恢复为你指定的 value

¥If you pass value without onChange, it will be impossible to select an option. When you control a select box by passing some value to it, you force it to always have the value you passed. So if you pass a state variable as a value but forget to update that state variable synchronously during the onChange event handler, React will revert the select box after every keystroke back to the value that you specified.

与 HTML 不同,不支持将 selected 属性传递给单个 <option>

¥Unlike in HTML, passing a selected attribute to an individual <option> is not supported.


React 中文网 - 粤ICP备13048890号