如何避免点击其他输入框后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
相关产品推荐
相关产品推荐

