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

如何避免点击其他输入框后Material Datepicker重新获得焦点

Material UI Datepicker 焦点异常问题:打开时焦点强制回退,关闭后自动重获焦点

问题现象

使用Material UI的Datepicker组件时,点击其关联的文本框可打开组件,但存在以下异常:

  • Datepicker处于打开状态时,尝试选中其他文本框,焦点会自动回到Datepicker的输入框
  • 关闭Datepicker后,即使未点击任何元素,它也会重新获得焦点

复现步骤

  • 点击Datepicker的输入框(不要点击日历图标)
  • 点击页面上的另一个文本框
  • 观察焦点强制回退到Datepicker输入框的现象

原代码

export default function BasicDatePicker() {
  const [value, setValue] = React.useState<Dayjs | null>(null);
  const [open, setOpen] = React.useState(false);

  return (
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <TextField placeholder='Click here while datepicker is opened' fullWidth={true} sx={{mb:2, mr: 2}}/>
      <DatePicker
        label="Basic example"
        value={value}
        onChange={(newValue) => {
          setValue(newValue);
        }}
        open={open}
        onOpen={() => setOpen(true)}
        onClose={() => setOpen(false)}
        renderInput={(props) => (
          <TextField {...props} onClick={(e) => setOpen(true)} />
        )}
      />
    </LocalizationProvider>
  );
}

问题原因

自定义的onClick事件与Material UI Datepicker内部的焦点管理逻辑冲突。组件默认会在打开时保持输入框焦点以防止组件意外关闭,而额外绑定的onClick会在焦点切换时触发打开逻辑,导致焦点被强制拉回。

解决方案

方案1:移除自定义onClick事件

Datepicker的renderInput返回的TextField已经内置了点击打开的逻辑,无需额外绑定:

export default function BasicDatePicker() {
  const [value, setValue] = React.useState<Dayjs | null>(null);
  const [open, setOpen] = React.useState(false);

  return (
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <TextField placeholder='Click here while datepicker is opened' fullWidth={true} sx={{mb:2, mr: 2}}/>
      <DatePicker
        label="Basic example"
        value={value}
        onChange={(newValue) => {
          setValue(newValue);
        }}
        open={open}
        onOpen={() => setOpen(true)}
        onClose={() => setOpen(false)}
        renderInput={(props) => (
          <TextField {...props} />
        )}
      />
    </LocalizationProvider>
  );
}

方案2:用onFocus替代onClick(保留点击输入框打开的需求)

如果需要点击输入框任意区域都打开Datepicker,改用onFocus事件避免与内部焦点逻辑冲突:

export default function BasicDatePicker() {
  const [value, setValue] = React.useState<Dayjs | null>(null);
  const [open, setOpen] = React.useState(false);

  return (
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <TextField placeholder='Click here while datepicker is opened' fullWidth={true} sx={{mb:2, mr: 2}}/>
      <DatePicker
        label="Basic example"
        value={value}
        onChange={(newValue) => {
          setValue(newValue);
        }}
        open={open}
        onOpen={() => setOpen(true)}
        onClose={() => setOpen(false)}
        renderInput={(props) => (
          <TextField {...props} onFocus={() => setOpen(true)} />
        )}
      />
    </LocalizationProvider>
  );
}

说明

移除自定义onClick或改用onFocus后,组件内部的焦点管理逻辑会正常运作,不会再强制将焦点拉回Datepicker输入框,同时保留Datepicker的正常打开/关闭功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:40:30