React按钮在iOS Chrome需两次点击触发问题求助
解决iPhone Chrome中React按钮需点击两次的问题
问题根源
你遇到的情况是因为移动端(包括iPhone的Chrome)没有原生鼠标hover事件,浏览器会把第一次触摸行为模拟成hover,同时中断了原本该触发的click事件。再加上你每次hover都会切换整个SVG组件,旧组件被卸载、新组件重新渲染,导致第一次触摸的事件上下文丢失,必须第二次触摸才能触发新组件的click。
解决方案
方案1:用CSS伪类控制SVG显示(推荐)
完全抛弃React的isHover状态,改用CSS的:hover伪类切换两个SVG的显示,组件不会重新渲染,触摸事件不会被打断:
修改组件代码:
const OptionsButton: FC<Props> = ({ disabled=false, className="options-button", onClick, style={cursor:'pointer',height:'34',width:'34',bottom:'15', right:'15',position:'absolute' } }) => { const handleClick = (e : React.MouseEvent<HTMLButtonElement>) => { onClick?.(e); e.stopPropagation(); } return ( <button className={`${className} options-btn-wrapper`} onClick={handleClick} style={style} disabled={disabled} > <OptionsBtn className="options-btn-default" /> <OptionsBtnPr className="options-btn-hover" /> </button> ) }
添加对应CSS:
.options-btn-wrapper { position: relative; height: 34px; width: 34px; } .options-btn-default, .options-btn-hover { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .options-btn-hover { display: none; } .options-btn-wrapper:hover .options-btn-hover { display: block; } .options-btn-wrapper:hover .options-btn-default { display: none; }
方案2:保留React状态但处理触摸事件
如果一定要用React的isHover状态,需要添加触摸事件监听,在触摸开始时直接触发点击逻辑,避免两次触摸:
const OptionsButton: FC<Props> = ({ disabled=false, className="options-button", onClick, style={cursor:'pointer',height:'34',width:'34',bottom:'15', right:'15',position:'absolute' } }) => { const [isHover, setIsHover] = useState(false); const handleMouseEnter = () => setIsHover(true); const handleMouseLeave = () => setIsHover(false); const handleClick = (e : React.MouseEvent<HTMLButtonElement>) => { onClick?.(e); e.stopPropagation(); } // 触摸时直接设置hover并触发点击 const handleTouchStart = (e: React.TouchEvent<HTMLButtonElement>) => { setIsHover(true); onClick?.(e as unknown as React.MouseEvent<HTMLButtonElement>); e.stopPropagation(); } return ( <button className={className} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} onClick={handleClick} onTouchStart={handleTouchStart} style={style} disabled={disabled} > {isHover ? <OptionsBtnPr /> : <OptionsBtn />} </button> ) }
方案3:合并SVG组件(最简洁)
如果SVG结构允许,把两个SVG合并成一个,通过CSS控制颜色、透明度等属性实现hover效果,完全避免组件切换的问题。
内容的提问来源于stack exchange,提问作者InfinityRP
相关产品推荐
相关产品推荐

