
本文介绍在 react 中构建支持动态切换环境(test/prod)并按需加载、勾选版本列表的复合型下拉组件,无需依赖特定第三方库,通过受控表单 + 状态管理 + 自定义弹层即可实现。
本文介绍在 react 中构建支持动态切换环境(test/prod)并按需加载、勾选版本列表的复合型下拉组件,无需依赖特定第三方库,通过受控表单 + 状态管理 + 自定义弹层即可实现。
在 React 应用中,标准 <select></select> 无法承载单选按钮(Radio)与复选框(Checkbox)混合交互逻辑,因此必须构建自定义下拉组件(Custom Dropdown)。其核心思路是:用一个可点击的触发器(如按钮或输入框)控制下拉面板的显隐,面板内部使用受控表单元素(<input type="radio"> 和 <input type="checkbox">),并通过 React 的 useState 和 useEffect 协同管理状态流。
关键实现步骤如下:
-
状态设计
-
isOpen: 控制下拉面板是否展开(布尔值) -
selectedEnv: 当前选中的环境('Test' | 'Prod') -
releases: 后端返回的版本数组(例如[{ id: 'v1.2', name: '1.2.0' }, ...]) -
selectedReleases: 已勾选的版本 ID 集合(推荐用Set<string></string>或string[])
-
-
交互逻辑
- 点击触发器 → 切换
isOpen - 改变 Radio → 清空当前
selectedReleases,设置selectedEnv,触发fetchReleases(selectedEnv) -
fetchReleases()返回后更新releases,此时复选框自动渲染并保持未勾选状态 - 复选框变更 → 动态更新
selectedReleases(注意避免直接 mutate state)
- 点击触发器 → 切换
-
UI 结构示意(精简版)
React Router Code Review下载审查 React Router 代码,确保数据加载、变更、错误处理和导航模式符合规范,适用于 React Router v6.4+ 代码、加载器及其他特性。
<div classname="custom-dropdown"> <button onclick="{()"> setIsOpen(!isOpen)}> {selectedEnv || 'Select environment'} ▼ </button><p>{isOpen && ( </p> <div classname="dropdown-panel" onclick="{e"> e.stopPropagation()}><fieldset> <legend>Environment</legend> <label><input type="radio" name="env" checked onchange="{()"> handleEnvChange('Test')} /> Test </label><label><input type="radio" name="env" checked onchange="{()"> handleEnvChange('Prod')} /> Prod </label> </fieldset> <pre class="brush:php;toolbar:false;"> {releases.length > 0 && ( <div classname="release-list"> <h4>Available Releases:</h4> {releases.map(r => ( <label key="{r.id}"> <input type="checkbox" checked onchange="{(e)"> setSelectedReleases(prev => e.target.checked ? new Set([...prev, r.id]) : new Set([...prev].filter(id => id !== r.id)) ) } /> {r.name} </label> ))} </div> )}










