React中如何实现点击输入框眼睛按钮后5毫秒自动隐藏secretID
现有逻辑存在的核心问题
- 状态设计有本质缺陷:没有把「API返回的真实secretID」和「界面展示的临时值」做状态拆分,反复把state里的
secretID赋值成掩码字符串,会直接覆盖掉接口返回的原始真实值。多次点击后根本取不到真实ID,只能在掩码字符串之间来回切换。 - 计时逻辑完全偏离需求:需求是点击后真实内容仅展示5毫秒,实际代码是延迟10毫秒才把真实值展示出来,再延迟100毫秒才切回掩码,真实值实际展示时长有90毫秒,而且点击后不会立刻展示内容,存在明显卡顿。
showID状态更新逻辑错位:输入框的取值依赖showID的判断,但当前代码是延迟10毫秒才翻转showID,切回掩码的时候根本没把showID重置为false。连续点击后,showID的状态会和实际展示内容完全不匹配,出现逻辑错乱。另外在延迟回调里直接用!this.state.showID更新状态,是类组件的经典闭包陷阱:回调执行时读到的this.state是点击瞬间的旧值,连续快速点击会导致状态翻转完全出错。- 没有定时器管理机制:每次点击都会新生成两个不受管控的
setTimeout,既不存储定时器ID,也不会在连续点击或者组件卸载时清理旧定时器,快速多次点击时会出现时序错乱——比如明明已经切回掩码,旧的延迟定时器触发后又突然把内容切成真实值,展示时长完全不可控。 - 兜底逻辑完全失效:因为
secretID的state已经被反复覆盖成掩码值,写的this.state.secretID ? this.state.secretID : "********"的兜底判断,根本取不到接口返回的原始真实ID,第一次切换把secretID改成掩码后,后续所有取值全是错误的。
符合需求的实现思路
- 拆分状态,从根源避免值被覆盖:
- 在state中单独存储从API获取的
realSecretID,这个值初始化后永远不会被掩码修改,作为真实ID的唯一来源 - 单独存
isShowSecret布尔状态,只用来控制当前输入框展示真实值还是掩码,不再来回修改具体的字符串值 - 输入框取值逻辑调整为:
value={isShowSecret ? realSecretID : HideID}
- 在state中单独存储从API获取的
- 修正计时逻辑匹配需求:
- 点击触发后立刻把
isShowSecret设为true,让真实值马上展示,去掉多余的10毫秒前置延迟 - 设置5毫秒的定时器,时间到了立刻把
isShowSecret设为false,切回掩码展示,完全匹配要求的展示时长
- 点击触发后立刻把
- 做好定时器管控:
- 把定时器ID存在组件实例上,每次触发toggle函数时,先清除上一次未执行完的定时器,再开启新的计时,避免快速点击导致的时序错乱
- 组件卸载时记得清理正在运行的定时器,避免内存泄漏
内容的提问来源于stack exchange,提问作者Nagasai ReactJumbo
相关产品推荐
相关产品推荐

