You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用useIonModal显示模态框时IonInput无法自动聚焦的问题排查

问题原因及解决方案

你的代码无法实现输入框自动聚焦,核心问题出在聚焦时机选择不当以及冗余的跨组件ref传递上:

1. 聚焦时机不对

onDidPresent是Ionic模态框的原生呈现事件,触发时仅代表模态框DOM结构挂载完成,但IonInput作为Web Component尚未完成内部初始化,同时Ionic的模态框焦点管理逻辑会优先将焦点锁定在模态框容器上,此时直接调用focus()会被拦截或失效。

2. Ref传递的冗余问题

从父组件传递ref到子组件的方式增加了不必要的复杂度,且无法确保ref在模态框每次呈现时都能正确同步到最新的DOM元素。


最优解决方案:子组件内部管理聚焦逻辑

直接在模态框组件内部使用Ionic React提供的useIonViewDidEnter生命周期钩子,该钩子会在模态框完全进入并完成渲染后触发,此时调用聚焦操作最可靠:

import { IonInput, useIonViewDidEnter } from '@ionic/react';
import { useRef } from 'react';

export interface UserViewModelModalProps extends ModalProps<AddUserViewModel> {}

export const UserViewModelModal: React.FC<UserViewModelModalProps> = (props) => {
  const usernameInputRef = useRef<HTMLIonInputElement>(null);

  // 模态框完全渲染完成后自动聚焦
  useIonViewDidEnter(() => {
    usernameInputRef.current?.focus();
  });

  return (
    <div className="wrapper ion-padding">
      <h1>Add User</h1>
      <IonInput
        label="Username"
        labelPlacement="fixed"
        ref={usernameInputRef}
      />
      <IonInput label="Password" labelPlacement="fixed" type="password" />
    </div>
  );
};

父组件代码简化

此时父组件无需传递ref,直接调用模态框即可:

const [presentAddUserModal, dismissAddUserModal] = useIonModal(
  UserViewModelModal,
  {
    dismiss: (data, role) => dismissAddUserModal(data, role),
  } as UserViewModelModalProps
);

// 触发模态框的代码保持不变
<IonFabButton
  onClick={() => {
    presentAddUserModal({
      cssClass: "popup-modal"
    });
  }}
>
  <IonIcon icon={add} />
</IonFabButton>

若坚持在父组件处理(不推荐)

如果必须在父组件中控制聚焦,可以通过setTimeout延迟调用,确保IonInput完成初始化:

presentAddUserModal({
  cssClass: "popup-modal",
  onDidPresent: () => {
    // 延迟100ms确保组件初始化完成
    setTimeout(() => {
      modalUsernameInput.current?.focus();
    }, 100);
  }
});

但这种方式依赖时间延迟,稳定性不如子组件内部使用生命周期钩子的方案。

内容的提问来源于stack exchange,提问作者Seiko Santana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:45:36