React+Fluent UI实现下拉框条件动态禁用选项的方法
React + Fluent UI 实现范围筛选下拉的选项联动禁用
实现原理
Fluent UI 的 IDropdownOption 类型原生支持 disabled 配置项,给对应选项设置该属性为true时,选项会自动置灰且不可点击,不需要额外写交互拦截逻辑。核心只需要根据起始下拉的选中值,动态生成结束下拉的选项列表,给符合禁用规则的选项加上disabled标识即可。
具体实现步骤
1. 补全原有DropdownId组件的缺失依赖
原有组件代码缺少React类型导入和样式文件导入,先补全修正:
import { Dispatch, SetStateAction } from 'react'; import { Dropdown, IDropdownStyles, IDropdownOption, } from "@fluentui/react"; // 替换为你项目实际的样式文件路径 import styles from './DropdownId.module.css'; interface DropdownProps { options: IDropdownOption[], placeholder: string, setDropdown: Dispatch<SetStateAction<string>> } const dropdownStyles: Partial<IDropdownStyles> = { dropdown: { width: 300 }, }; export const DropdownId = (props: DropdownProps) => { return ( <div className={styles.root}> <Dropdown placeholder={props.placeholder} options={props.options} styles={dropdownStyles} onChange={(_, option) => { // 加空值兜底,避免选中空选项时key为undefined props.setDropdown(`${option?.key ?? ''}`) }} /> </div> ); };
2. 在父组件中动态生成结束下拉的选项列表
在使用两个下拉组件的父组件(index.tsx)中,根据起始下拉的选中值,计算需要禁用的选项:
import { useState, useEffect } from 'react'; // 原有状态声明,如果你已经声明可忽略 const [startObjectId, setStartObjectId] = useState<string>(''); const [endObjectId, setEndObjectId] = useState<string>(''); const [buttonClicked, setButtonClicked] = useState<boolean>(false); // 计算起始选中项在选项列表中的索引 const selectedStartIndex = apiTagsResponse.findIndex(tag => tag === startObjectId); // 动态生成结束下拉的选项,命中规则的选项设置disabled const endDropdownOptions = apiTagsResponse.map((tag, index) => ({ text: tag, key: tag, // 当起始值已选中,且当前选项索引小于等于起始项索引时禁用 disabled: selectedStartIndex !== -1 && index <= selectedStartIndex })); // 监听起始值变化,自动清空落在禁用区间的非法结束值 useEffect(() => { if (!startObjectId || !endObjectId) return; const currentEndIndex = apiTagsResponse.findIndex(tag => tag === endObjectId); if (currentEndIndex !== -1 && currentEndIndex <= selectedStartIndex) { setEndObjectId(''); } }, [startObjectId, selectedStartIndex, endObjectId, apiTagsResponse, setEndObjectId]);
3. 修改组件传参,使用动态生成的选项
把原来传给结束下拉的静态options替换为带禁用规则的动态选项:
<Container> <DropdownId options={apiTagsResponse.map(tag => ({ text: tag, key: tag }))} setDropdown={setStartObjectId} placeholder="Set Start Tag" /> </Container> <Container>to</Container> <Container> <DropdownId options={endDropdownOptions} setDropdown={setEndObjectId} placeholder="Set End Tag" /> </Container> <Container> <DropdownApplyFilterButton onClick={() => setButtonClicked(true)} /> </Container>
注意点
- 选项禁用的判断完全依赖
apiTagsResponse的返回顺序,只要下拉展示顺序和接口返回顺序一致,索引判断就不会出错 - 新增的结束值合法性校验可以避免用户先选结束值、再改起始值后,出现结束值小于等于起始值的无效筛选条件
- 所有禁用逻辑复用Fluent UI原生能力,不需要额外写自定义样式或者点击事件拦截
内容的提问来源于stack exchange,提问作者tamila
相关产品推荐
相关产品推荐

