同表单使用两个react-select下拉组件出现id重复报错如何解决
问题现象
项目中同时使用两类基于react-select实现的下拉组件:
- 基于react-select封装的
react-timezone时区选择组件 - 官方原生
react-select下拉选择组件
单独加载任意组件时功能运行正常,在同一个表单内同时引入两个组件时,控制台抛出如下DOM id重复报错:
[DOM] Found 2 elements with non-unique id #react-select-3-input:
报错涉及的重复id为组件内部自动生成,并非业务JSX代码手动定义。
业务侧编写的时区选择组件代码如下:
<TimezoneSelect id="timezone-select" className="select-box" value={timezone} onChange={setTimezone} theme={(theme) => ({ ...theme, borderRadius: 0, colors: { ...theme.colors, primary25: "#ecf1f5", primary: "#0f4c81", }, })} />
业务侧编写的普通react-select组件代码如下:
<Select id="select-num" className="select-box" options={options} value={value} onChange={setValue} theme={(theme) => ({ ...theme, borderRadius: 0, colors: { ...theme.colors, primary25: "#ecf1f5", primary: "#0f4c81", }, })} />
问题根因
react-select默认靠内部维护的全局计数器,给内部的input元素生成自增格式的id,你在组件上传递的id属性只会挂载到组件最外层容器,不会干预内部input的id生成逻辑。
出现id重复的核心原因是:react-timezone将react-select作为内部依赖打包,自带一份独立的react-select运行实例,和项目中直接引入的原生react-select实例完全隔离。两份实例各自维护独立的id计数器,计数从相同初始值开始累加,最终生成了完全相同的内部input id,触发DOM非唯一id报错。
解决方案
以下方案按改造成本从低到高排列,可任选其一修复:
- 手动指定实例id:给两个组件分别传入唯一的
instanceId属性,强制组件使用传入的标识作为id生成前缀,跳过全局自动计数逻辑。这是成本最低的修复方式,修改后代码示例:
{/* 时区选择组件 */} <TimezoneSelect id="timezone-select" instanceId="timezone-select-instance" className="select-box" value={timezone} onChange={setTimezone} theme={(theme) => ({ ...theme, borderRadius: 0, colors: { ...theme.colors, primary25: "#ecf1f5", primary: "#0f4c81", }, })} /> {/* 普通下拉选择组件 */} <Select id="select-num" instanceId="num-select-instance" className="select-box" options={options} value={value} onChange={setValue} theme={(theme) => ({ ...theme, borderRadius: 0, colors: { ...theme.colors, primary25: "#ecf1f5", primary: "#0f4c81", }, })} />
- 手动指定内部input id:如果仅需要解决input id重复问题,也可以给两个组件分别传入唯一的
inputId属性,直接覆盖内部input元素自动生成的id值,同样可以规避重复问题。 - 依赖去重:检查项目中直接引入的react-select版本,和
react-timezone依赖的react-select版本是否一致,通过包管理工具的依赖去重能力(如npm dedupe、pnpm/yarn的依赖提升配置),让两个组件共用同一份react-select运行实例,共享同一个id计数器,从根源上消除计数隔离带来的id冲突。
内容的提问来源于stack exchange,提问作者A. E.
相关产品推荐
相关产品推荐

