React中为输入框切换type时如何正确使用setTimeout?
解决日期输入框切换类型时误触失焦的问题
问题说明
需求是实现一个仅显示placeholder的日期输入框:点击输入框时将type从text切换为date;若输入框为空,鼠标离开3秒后自动切回text类型。但直接在onMouseLeave中调用setTimeout会导致组件渲染时就触发定时器,且误触鼠标离开后,定时器依然会执行,导致输入框变回text无法继续输入日期。
问题根源
原代码中onMouseLeave={setTimeout(handleText, 3000)}的写法错误,这会在组件挂载时立即执行setTimeout,而非鼠标离开时才触发。同时没有处理用户再次操作输入框的场景,定时器一旦启动就会执行,无法中断。
解决方案
使用useRef保存定时器ID,在鼠标离开时启动定时器,当用户再次进入输入框或输入框获得焦点时清除定时器,确保不会在用户操作过程中切回text类型。
修改后的代码
import { useState, useRef } from 'react'; // ... 其他业务逻辑 const [type, setType] = useState("text"); const timerRef = useRef(null); // 保存定时器ID的ref const handleDate = () => { setType("date"); // 清除之前的定时器,避免切换为date后仍被切回text if (timerRef.current) { clearTimeout(timerRef.current); timerRef.current = null; } }; const handleText = () => { if (values.birthday === "") { setType("text"); } timerRef.current = null; }; const handleMouseLeave = () => { // 鼠标离开时启动3秒定时器 timerRef.current = setTimeout(handleText, 3000); }; const handleMouseEnter = () => { // 鼠标再次进入时清除定时器 if (timerRef.current) { clearTimeout(timerRef.current); timerRef.current = null; } }; const handleFocus = () => { // 输入框获得焦点时也清除定时器,确保输入不受影响 if (timerRef.current) { clearTimeout(timerRef.current); timerRef.current = null; } }; // ... 其他业务逻辑
对应的input组件:
<input onChange={handleChange} value={values.birthday} type={type} name="birthday" placeholder="birthday" onClick={handleDate} onMouseLeave={handleMouseLeave} onMouseEnter={handleMouseEnter} onFocus={handleFocus} />
逻辑说明
timerRef用来存储定时器ID,方便后续清除定时器- 鼠标离开输入框时才启动3秒定时器,而非组件初始化时执行
- 当用户再次将鼠标移入输入框,或输入框获得焦点时,立即清除定时器,避免误触后输入框被强制切回
text类型 - 只有当用户真正离开输入框超过3秒且输入框为空时,才会将type切回
text
内容的提问来源于stack exchange,提问作者Spluli
相关产品推荐
相关产品推荐

