如何为自定义React下拉框组件实现必填校验效果
改造实现方案
整个改造复用浏览器原生表单校验能力,不需要额外编写提交拦截逻辑,和普通原生输入框的required行为完全一致。
1. 标签旁红星提示实现
首先在组件入参解构时新增required参数,替换原有的label渲染逻辑,当required为真时在label文本后追加红色星标:
原label渲染代码:
{label && <label>{label}</label>}
替换为:
{label && ( <label> {label} {required && <span className="c-dropdown__required-star">*</span>} </label> )}
在对应的SCSS文件中追加星标样式:
.c-dropdown { position: relative; // 为后续隐藏校验元素提供定位上下文 &__required-star { color: #ff4d4f; margin-left: 4px; } }
2. 原生表单必填校验实现
当前下拉框由div手动搭建,不具备原生表单元素的校验能力。只需要在组件内部嵌入一个完全隐藏的原生input,将校验逻辑全部交由该input处理,即可实现和普通input加required完全一致的效果:未选值时拦截表单提交、自动弹出浏览器默认校验提示。
在组件最外层(c-dropdown类名的div内部)追加如下隐藏input:
<input type="text" required={required} value={selected ?? ''} onChange={() => {}} aria-hidden="true" tabIndex={-1} style={{ width: 0, height: 0, opacity: 0, position: 'absolute', left: 0, top: 0, pointerEvents: 'none' }} />
该input的设计逻辑:
- 直接绑定组件已有的
selected值,使用空值合并运算符??同步为空字符串时,不会把合法的0值选项误判为空,选中选项后会自动同步为有效值,校验自动通过 - 绑定
required属性,未选值时(value为空字符串)会被原生表单识别为校验不通过,拦截提交 - 全透明、宽高为0、禁用鼠标事件、不参与键盘导航,完全不会影响现有UI和交互
3. 补全组件类型定义
在组件的PropTypes定义中追加required的类型声明,同时在默认参数中设置默认值:
Dropdown.propTypes = { // 保留原有所有propTypes定义 required: PropTypes.bool, }; Dropdown.defaultProps = { // 保留原有所有默认参数 required: false, };
最终效果
改造完成后:
- 开启required的字段,标签旁会显示红色星标
- 未选中任何选项时,表单提交会被浏览器自动拦截,弹出默认校验提示
- 选中任意有效选项后,校验自动通过,可正常提交表单
内容的提问来源于stack exchange,提问作者Jean Pierre
相关产品推荐
相关产品推荐

