Ionic + React应用中IonModal内的IonInput/OtpInput如何实现自动聚焦
Ionic + React 弹窗内输入框自动聚焦解决方案
核心失效原因
IonModal 组件内部DOM挂载存在时序差:当 isOpen 设为true时,子元素不会立刻完成挂载插入文档流,此时内置的autofocus属性、第三方组件的自动聚焦逻辑都会因为目标元素不存在而失效。
可用方案
1. 监听Modal完全展示事件触发聚焦(最稳定)
IonModal 暴露了 onIonModalDidPresent 事件,该事件仅在Modal完全渲染完成、可交互后触发,此时再执行聚焦逻辑可稳定命中目标元素。
代码示例:
import { useRef } from 'react'; import OtpInput from "react-otp-input"; import { IonInput, IonModal } from '@ionic/react'; const OtpModal = (props) => { // OtpInput 对应ref,绑定内部第一个输入框 const otpInputRef = useRef<HTMLInputElement>(null); // IonInput 对应ref const ionInputRef = useRef<HTMLIonInputElement>(null); const onModalReady = () => { // 聚焦Otp输入框 otpInputRef.current?.focus(); // 若需要聚焦IonInput,调用IonInput内置的setFocus方法 // ionInputRef.current?.setFocus(); }; return ( <IonModal isOpen={true} cssClass={classes.someClass} showBackdrop={false} // 关键:绑定Modal就绪事件 onIonModalDidPresent={onModalReady} > <OtpInput value={props.otp} numInputs={6} // 绑定ref到第一个输入框 inputRef={otpInputRef} /> {/* IonInput写法示例 <IonInput ref={ionInputRef} type="number" label="Enter OTP" /> */} </IonModal> ); };
2. 兼容旧版react-otp-input的方案
如果你使用的react-otp-input版本不支持inputRef属性,可以给输入框加自定义类名,在Modal就绪后通过选择器查找元素:
const onModalReady = () => { const firstOtpInput = document.querySelector('.custom-otp-input input:first-of-type') as HTMLInputElement; firstOtpInput?.focus(); }; // OtpInput配置 <OtpInput value={props.otp} numInputs={6} containerStyle="custom-otp-input" />
注意事项
- 不要依赖原生
autofocus属性,Ionic生态下弹窗内元素的原生自动聚焦兼容性极差 - IonInput不要直接调用原生DOM的focus方法,必须使用组件暴露的
setFocus()异步方法 - Modal每次打开都会触发
onIonModalDidPresent事件,无需额外处理重复打开的聚焦逻辑
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

