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

React.js中如何解决useConfirmDialog弹窗内文本输入框输入时失焦问题

问题根因

输入框自动失焦本质是组件被卸载后重新挂载导致的,核心触发点有两处:

  1. useConfirmDialog 中返回的 Dialog 是每次Hook执行时重新定义的函数组件,只要父组件状态更新,React就会将其识别为全新的组件,销毁旧实例并挂载新实例,输入框的焦点自然会丢失。
  2. 传递给 useConfirmDialog 的 inputArea 是内联编写的JSX,每次父组件渲染都会生成新的JSX对象,也会触发弹窗内容的整体重渲染。

修复步骤

1. 修改useConfirmDialog逻辑

不要返回函数组件,直接返回已经渲染完成的React元素,修改Confirmdialog.tsx中的代码:

export const useConfirmDialog = (
  props: ConfirmDialogProps
): [() => void, ReactElement] => {
  const [show, setShow] = useState(false);

  function toggleDialog() {
    setShow((show) => !show);
  }

  // 直接返回渲染后的元素,不要返回函数组件
  const dialog = (
    <ConfirmDialogModal
      key="confirmDialog"
      {...props}
      open={show}
      toggleDialog={toggleDialog}
    />
  );
  return [toggleDialog, dialog];
};

2. 调整弹窗渲染方式

原来调用弹窗的写法 <CloneConfirm /> 直接改为 {CloneConfirm} 即可,不需要再加括号执行。

3. 优化重渲染逻辑(可选,进一步避免同类问题)

  • 用 useMemo 缓存 inputArea,仅在依赖变化时重新生成:
const inputArea = useMemo(() => (
  <TextInput
    type="text"
    id="kc-name"
    name="name"
    value={clonedRoleName}
    onChange={(val) =>
      onChangeHandler({
        target: { value: val, name: 'name' },
      })
    }
  />
), [clonedRoleName, onChangeHandler])

const [toggleCloneDialog, CloneConfirm] = useConfirmDialog({
  titleKey: 'roles:cloneRole',
  messageKey: deleteMessage,
  continueButtonLabel: 'roles:clone',
  inputArea: inputArea,
  continueButtonVariant: ButtonVariant.primary,
  onConfirm: async () => {
    clone();
  },
});
  • 用 useCallback 缓存 onChangeHandler,避免每次渲染生成新的函数实例:
const onChangeHandler = useCallback((event) => {
  const { value } = event.target;
  setClonedRoleName(value);
}, []);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 07:45:04