Next.js/React实现自定义URL按钮切换功能异常解决方案
问题根源
你的代码存在3个核心问题,导致效果不符合预期:
- 自定义编辑状态下,你把「Cancel」和「Save」直接作为字符串拼接在同一个
<p>标签内,两个操作没有独立的DOM元素,根本无法绑定单独的事件处理函数,点击整个区域只会触发绑定在<p>上的同一个状态翻转逻辑,自然无法实现分开的交互。 - 状态定义冗余:
active和show两个状态始终同步切换,重复定义没有实际价值,反而容易导致逻辑不一致。 - 没有为取消、保存操作单独实现业务逻辑,所有点击行为都只做状态切换,既不能在取消时回退用户的临时输入,也不能在保存时提交自定义链接配置。
修复方案
按以下步骤调整即可实现预期效果:
- 删除冗余的
show状态,统一使用active变量标识是否处于自定义链接编辑模式,简化状态逻辑。 - 替换原来
<p>标签内拼接文本的写法,改为条件渲染:- 非编辑状态:只渲染「Create Custom URL」操作入口
- 编辑状态:渲染两个独立的
<button>元素,分别绑定取消、保存对应的处理函数
- 单独实现两个操作的逻辑:
- 取消:将输入框内容重置为当前生效的官方分享链接,退出编辑模式,恢复显示复制按钮
- 保存:校验用户输入的自定义链接后缀合法性,更新分享链接配置,退出编辑模式
修改后完整代码
const ShareKey = ({ surveyId, shareKey = "", setShareKey, refProps }) => { const [isLoading, setIsLoading] = useState(false); const baseShareUrl = process.env.NEXT_PUBLIC_SHARE_URL + "/"; const [customInput, setCustomInput] = useState(baseShareUrl); const [active, setActive] = useState(false); const getLink = () => { setShareKey(""); setIsLoading(true); automaticApproval({ surveyId }) .then((resolve) => { console.log(resolve); setShareKey(resolve.key); // 生成新链接后同步重置输入框默认值 setCustomInput(baseShareUrl + resolve.key); }) .catch((reject) => { console.log(reject); toast.error(reject); }) .finally(() => { setIsLoading(false); }); }; // 取消操作处理 const handleCancel = () => { // 回退输入框内容到当前生效的分享链接 setCustomInput(baseShareUrl + shareKey); setActive(false); }; // 保存操作处理 const handleSave = () => { const customKey = customInput.replace(baseShareUrl, ""); if (!customKey.trim()) { toast.error("自定义链接后缀不能为空"); return; } // 替换为实际保存自定义链接的接口逻辑 setShareKey(customKey); setActive(false); toast.success("自定义链接保存成功"); }; return ( <section> <button onClick={getLink} disabled={isLoading} className={styles.link_button}> {`GENERATE ${shareKey && "NEW "}LINK`} </button> {shareKey && ( <div className={styles.link_container}> <label>Share link</label> <div className={styles.link}> <input value={active ? customInput : baseShareUrl + shareKey} onChange={(e) => { setCustomInput(e.target.value); }} disabled={!active} ref={refProps} /> {!active && <button onClick={() => { if (typeof navigator !== "undefined") { navigator.clipboard.writeText(refProps.current.value); toast.info("Copied to clipboard"); } }} > copy </button> } </div> <div className={styles.custom}> {!active ? ( <button onClick={() => setActive(true)}> Create Custom URL </button> ) : ( <> <button onClick={handleCancel}>Cancel</button> <button onClick={handleSave}>Save</button> </> )} </div> </div> )} </section> ); };
调整后给两个操作按钮加对应的间距样式,就能完全匹配预期的UI效果,两个按钮的点击事件完全独立,不会互相干扰。
内容的提问来源于stack exchange,提问作者Kia Kalista
相关产品推荐
相关产品推荐

