2024-06-20 03:49PM
参考:https://fr.react.dev/reference/react-dom/components/select#select
React select
浏览器的内置<select>通过使用组件,可以呈现包含option的选择框
<select>
<option value="someOption">Some option</option>
<option value="otherOption">Other option</option>
</select>
1.用法
1)显示带有选项的选择框
2)为选择框提供label属性
3)提供选项初始值
4)支持多选
5)提交表单时读取选择框的值
6)使用State控制选择框
2.props
<select>支持所有常见的props element
2.1你可以通过传递value属性以控制选择框:
当你传递value时,必须同时传递一个onChange处理函数,用于更新传递的值。
2.2如果<select>是非受控组件,那么你应该传递defaultValue参数:
以下<select>属性均可用于受控与非受控选择框组件:
1)autoComplete:字符串,用于指定可能的自动完成行为之一。
2)autoFocus:布尔值。如果为true,React将挂载时聚焦该元素。
3)children:<select>接受<option>、<optgroup>与<datalist>组件作为子元素。只要最终渲染的是其中之一,你就可以传递自己的组件。如果最终渲染的是<option>,则每个<option>都必须具有value属性。
4)disable:布尔值,如果为true,选择框将不会交互并展示为暗淡状态(dimmed)。
5)form:字符串,表示选择框所属的<form>的id。如果未指定,则为最近的父表单。
6)multiple:布尔值。如果为true,则浏览器允许多选。
7)name:字符串,用于指定此选择框的名称,该名称将在提交表单时一起提交。
8)onChange:一个Event处理函数,其对于受控选择框时必需的。当用户选择不同的选择项时立即触发。此行为类似于浏览器input事件。
9)onChangeCapture:与onChange类似,但是是在捕获阶段触发的。
10)onInput:一个Event处理函数。当用户更改值时立即触发。由于历史原因,在React习惯于使用onChange,工作方式类似。
11)onInputCapture:与onInput类似,但是是在捕获阶段触发的。
12)onInvalid:一个Event处理函数。如果输入的内容在表单提交时未通过验证,则会触发此事件。与内置的invalid事件不同,React的onInvalid事件可以进行冒泡。
13)onInvalidCapture:与onInvalid类似,但是是在捕获阶段触发的。
14)require:布尔值。如果为true,则必须提供值才能提交表单。
15)size:数字。当指定multiple={true}时可选,表示同时可见的项目数。
注意:
1)与HTML不同,在<option>上传递selected属性将不受支持,你应该使用<select defaultValue>处理非受控选择框;而使用<select value>处理受控选择框
2)如果选择狂收到value属性,它将被视为受控组件
3)选择框不能同时受控与非受控
4)选择框在其生命周期内无法在受控与非受控之间切换
5)每个受控选择框都需要onChange事件处理程序,它会同步更新其后备值。
3.用法:
3.1 显示带有选项的选择框
渲染一个包含一系列<option>组件的<select>,来展示一个选择框,并给每个<option>都设置一个value属性,表示要与表单一起提交数据。
src/pages/select.jsx 文件的代码内容如下:
import React from 'react';
export default function FruitPicker() {
return (
<label>
选择一个水果:
<select name="精选水果">
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="桃子">桃子</option>
</select>
</label>
);
}
页面展示情况如下:
没有点击下拉单:
点击下拉单选择其他水果:
3.2 为选择框提供label属性
一般而言,应该将每个<select>标签都放在<label>标签内,表示此标签与该选择框相关联。当用户单击标签是,浏览器将会自动读取下拉单,这对于用户访问也非常重要:当用户点击下拉单时,浏览器将显示标题
如果无法将<select>放置在<label>内,请通过将相同的ID传递给<select id>与<label htmlFor>来将他们关联起来。为了避免一个组件的多个实例之间的冲突,使用useId生成这样的ID
src/pages/selectLabel.jsx 文件的代码内容如下:
import React, { useId } from 'react';
export default function Form() {
const vegetableSelectId = useId();
return (
<>
<label>
请选择一种水果:
<select name="精选水果">
<option value="桃子">桃子</option>
<option value="芒果">芒果</option>
<option value="西瓜">西瓜</option>
</select>
</label>
<hr />
<label htmlFor={vegetableSelectId}>
请选择一种蔬菜:
</label>
<select id={vegetableSelectId} name="精选蔬菜">
<option value="土豆">土豆</option>
<option value="生菜">生菜</option>
<option value="玉米">玉米</option>
</select>
</>
);
}
页面展示情况如下:
没有点击下拉单:
点击下拉单选择其他水果和蔬菜:
3.3 提供选项初始值
在默认情况下,浏览器会把select第一个<option>作为初始值。你可以将其他<option>的value作为defaultValue传递给<select>组件
src/pages/selectDefaultValue.jsx 文件的代码内容如下:
import React from 'react';
export default function FruitPickerDefault() {
return (
<label>
选择一个水果:
<select name="精选水果" defaultValue="菠萝蜜">
<option value="百香果">百香果</option>
<option value="哈密瓜">哈密瓜</option>
<option value="菠萝蜜">菠萝蜜</option>
</select>
</label>
);
}
页面展示情况如下:
没有点击下拉单:
点击下拉单选择其他水果:
3.4 支持多选
你可以通过在<select>指定multiple={true}设置多选。但如果这样做,那么你也应该向defaultValue传递一个字符串,以指定选中初始值
src/pages/selectMultiple.jsx 文件的代码内容如下:
import React from 'react';
export default function FruitPickerMultiple() {
return (
<>
<label>
选择一些水果:
</label><br/>
<select
name="精选水果"
defaultValue={['榴莲', '西柚']}
multiple={true}
>
<option value="柠檬">柠檬</option>
<option value="榴莲">榴莲</option>
<option value="西柚">西柚</option>
</select>
</>
);
}
页面展示情况如下:
3.5 提交表单时读取选择框的值
在选择框周围添加一个包含<button type="submit">按钮的<form>组件,这将调用<form onSubmit>时间处理程序。默认情况下,浏览器将向当前URL发送表单数据并刷新页面。你可以通过哦调用e.preventDefault()取消此默认行为,并使用new
FormData(e.target)读取表单数据。
src/pages/editPost.jsx 文件的代码内容如下:
import React from 'react';
export default function EditPost() {
function handleSubmit(e) {
// 阻止浏览器重新加载页面
e.preventDefault();
// 读取表单数据
const form = e.target;
const formData = new FormData(form);
// 你可以直接将 formData 作为fetch的请求body
fetch('/some-api', { method: form.method, body: formData});
// 你可以像浏览器默认的一样,将其转换为URL
console.log(new URLSearchParams(formData).toString());
// 也可以使用普通的对象
const formJson = Object.fromEntries(formData.entries());
console.log(formJson); // (!)这并不包含多选值
// 或者你可以使用name与value相匹配的数组对
console.log([...formData.entries()]);
}
return (
<form method="post" onSubmit={handleSubmit}>
<label>
选择你喜欢的水果:
<select name="精选水果" defaultValue="橘子">
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="橘子">橘子</option>
</select>
</label>
<hr/>
<label>
选择你所有喜欢的蔬菜:
<select name="精选蔬菜" multiple={true} value={['玉米', '番茄']}>
<option value="黄瓜">黄瓜</option>
<option value="玉米">玉米</option>
<option value="番茄">番茄</option>
</select>
</label>
<hr/>
<button type="reset">重置</button>
<button type="submit">提交</button>
</form>
);
}
页面展示情况如下:
没有点击下拉单:
点击下拉单之后,查看控制台日志:
给<select>添加name属性,例如:<select name="selectedFruit"/>指定的name将作为表单数据中的一个键,例如{ selectedFruit: "orange"}
如果使用了<select multiple={true}>那么你从表单中读取的FormData将会将每个选项作为单独name与value相匹配的键值对包含在内。仔细查看上面示例中的控制台日志
注意:默认情况下,<form>内的任何<button>都可以提交表单。如果你有自定义Button组件,请考虑使用<button type="button">而不是<button>,如果你想要明确指定提交表单的按钮,请使用<button type="submit">
3.6 使用state控制选择框
像<select />这样的选择框是非受控的。即使你传递了初始值,比如<select defaultValue="orange" />,你的JSX也只是指定了初始值,而非当前时刻的值
如果要渲染一个受控选择框,请传递value属性给选择框。通常,你可以通过声明一个state来控制选择框:
src/pages/selectState.jsx 文件的代码内容如下:
import React, { useState } from 'react';
export default function SelectState() {
// 声明一个state变量
const [selectedFruit, setSelectedFruit] = useState('香蕉')
return (
<select
// 强制选择框的值与state相匹配
value={selectedFruit}
// 并在每次改变(change)时更新state
onChange={(e) => setSelectedFruit(e.target.value)}
>
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="梨">梨</option>
</select>
);
}
页面展示情况如下:
点击下拉单选择其他水果:
这可以帮助你在每次选择时都触发重新渲染
src/pages/selectFruitState.jsx 文件的代码内容如下:
import React, { useState } from 'react';
export default function SelectFruitState() {
const [selectedFruit, setSelectedFruit] = useState('橘子');
const [selectedVegs, setSelectedVegs] = useState(['豆角', '冬瓜']);
return (
<>
<label>
选择一个水果:
<select
value={selectedFruit}
onChange={e => setSelectedFruit(e.target.value)}
>
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="橘子">橘子</option>
</select>
</label>
<hr />
<label>
选择所有你喜欢的蔬菜:
<select
multiple={true}
value={selectedVegs}
onChange={e => {
const options = [...e.target.selectedOptions];
const values = options.map(option => option.value);
setSelectedVegs(values);
}}
>
<option value="豆角">豆角</option>
<option value="菠菜">菠菜</option>
<option value="冬瓜">冬瓜</option>
</select>
</label>
<hr />
<p>你最喜欢的水果是:{selectedFruit}</p>
<p>你最喜欢的蔬菜是:{selectedVegs.join(',')}</p>
</>
);
}
页面展示情况如下:
点击下拉单选择其他水果和蔬菜:
注意:如果传递了value但没有传递onChange,那么将无法选择选项。当你通过传递value来控制选择框是,你需要保证选择框始终具有你传递的值。因此,如果你将一个state作为value传递,但在onChange事件处理程序中忘记同步更新该状态变量,
React将在每次按键后将选择框恢复到你指定的value。
与HTML不同,在<option>上传递selected属性将不受支持。
登录
请登录后再发表评论。
评论列表:
目前还没有人发表评论