React TagsInput组件如何禁止重复标签录入并展示对应提示
你可以在现有代码基础上做少量调整,即可实现禁止重复内容录入为标签的能力,核心改动点如下:
- 新增独立的重复值校验状态,和原有URL格式校验状态拆分,支持分别展示不同的错误提示
- 提交逻辑中新增重复值判断:对输入内容做首尾去空处理后,和已有标签列表逐一比对,命中重复则直接拦截提交
- 输入内容变化时自动重置重复校验状态,避免用户修改输入后旧的错误提示残留
修改后的完整代码如下:
import { useState } from 'react'; export default function TagsInputRequestURL(props) { const {tags, setTags} = props; const [input, setInput] = useState(""); const [isValid, setIsValid] = useState(true); // 新增重复值错误状态 const [isDuplicate, setIsDuplicate] = useState(false); const onChange = (e) => { const { value } = e.target; if (value) { setIsValid(() => /^(ftp|https?):\/\/[^ "]+$/.test(value)); } else { setIsValid(true); } // 输入变化时重置重复错误提示 setIsDuplicate(false); setInput(value); }; const onSubmit = (e) => { e.preventDefault(); const trimmedInput = input.trim(); // 空值直接拦截 if (!trimmedInput) return; // 格式校验不通过直接返回 if (!isValid) return; // 重复值校验 const hasDuplicate = tags.some(tag => tag.trim() === trimmedInput); if (hasDuplicate) { setIsDuplicate(true); return; } // 校验全部通过后新增标签 setTags((tags) => [...tags, trimmedInput]); setInput(""); setIsValid(true); }; const deleteTag = (index) => { setTags((prevState) => prevState.filter((tag, i) => i !== index)); }; return ( <div className={classes.container}> {tags.map((tag, index) => <div className={classes.tag} key={tag + index}> <ClearIcon className={classes.del} fontSize="big" onClick={() => deleteTag(index)} /> {tag} </div> )} <form onSubmit={onSubmit}> <input className={classes.input} value={input} placeholder={props.inputPlaceholder} onChange={onChange} /> {!isValid && <small style={{ color: "red" }}>请输入合法的URL地址</small>} {isDuplicate && <small style={{ color: "red" }}>该标签已存在,请勿重复添加</small>} </form> </div> ); }
补充说明:代码里对输入内容和已有标签统一做了首尾去空处理,避免用户通过在内容前后加空格的方式绕过重复校验;同时给标签渲染项补充了key属性,符合React列表渲染的规范要求。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

