如何修复Material-UI Dialog中TextField光标消失的焦点异常?
我正在公司搭建内部网站,在实现基于权限的访问控制(Permission-based-access control)后,尝试创建用户角色创建功能。当前遇到的问题是:点击Dialog内的TextField时光标持续消失,完全无法输入内容,仅能通过同时快速点击TextField和敲击键盘的方式输入值,且未收到任何报错信息。
我直接使用Material-UI提供的表单对话框(Form Dialog)组件,将其导入到父组件中使用,暂未关联任何自定义函数。我分别在Dialog标签内部和外部添加了额外的<input type="text" />进行测试,发现Dialog内部的<input type="text" />存在同样问题,但外部的可正常使用。
组件代码如下:
import React from 'react'; import Button from '@material-ui/core/Button'; import TextField from '@material-ui/core/TextField'; import Dialog from '@material-ui/core/Dialog'; import DialogActions from '@material-ui/core/DialogActions'; import DialogContent from '@material-ui/core/DialogContent'; import DialogContentText from '@material-ui/core/DialogContentText'; import DialogTitle from '@material-ui/core/DialogTitle'; export default function FormDialog() { const [open, setOpen] = React.useState(false); const handleClickOpen = () => { setOpen(true); }; const handleClose = () => { setOpen(false); }; return ( <div> <Button variant="outlined" color="primary" onClick={handleClickOpen}> Open form dialog </Button> <input type="text" /> <Dialog open={open} onClose={handleClose} aria-labelledby="form-dialog-title"> <input type="text" /> <DialogTitle id="form-dialog-title">Subscribe</DialogTitle> <DialogContent> <DialogContentText> To subscribe to this website, please enter your email address here. We will send updates occasionally. </DialogContentText> <input type="text" /> <TextField autoFocus margin="dense" id="name" label="Email Address" type="email" fullWidth /> </DialogContent> <DialogActions> <Button onClick={handleClose} color="primary"> Cancel </Button> <Button onClick={handleClose} color="primary"> Subscribe </Button> </DialogActions> </Dialog> </div> ); }
这种光标莫名消失的问题我之前在项目里也碰到过几次,结合你的场景,给你几个排查方向:
先排查层级冲突问题:最常见的原因就是Dialog的z-index不够,被页面上其他元素(比如权限控制逻辑里的全局遮罩、侧边栏弹窗)盖住了。你看着是点到了输入框,但实际焦点被上层的透明元素抢走了。试试给Dialog手动加个更高的z-index,比如:
<Dialog open={open} onClose={handleClose} aria-labelledby="form-dialog-title" style={{ zIndex: 1300 }}>Material-UI默认Dialog的z-index是1200,往上调个100应该能避开大部分冲突。
回溯权限控制的影响:你提到是做完权限访问控制后才出的问题,这大概率是权限逻辑带来的副作用。比如权限组件可能加了全局的点击事件监听、渲染了覆盖整个页面的遮罩层,或者做了全局的焦点管理,这些都可能干扰Dialog内部的输入框。可以先临时注释掉权限相关的代码,测试Dialog是否正常,逐步定位是哪部分权限逻辑导致的。
检查不必要的重渲染:如果父组件有频繁的状态更新,可能会导致Dialog被反复重渲染,输入框的焦点就会跟着丢失。给你的FormDialog组件套个
React.memo,避免无意义的重渲染试试:export default React.memo(function FormDialog() { // 原组件内容不变 });验证Material-UI版本:有些旧版本的Material-UI在Dialog的焦点管理上有bug,你可以看看当前用的@material-ui/core版本是不是比较老,升级到对应大版本的最新稳定版(比如v4.x的最新版),说不定官方已经修复了这个问题。
排除浏览器扩展干扰:偶尔也会遇到浏览器扩展搞鬼的情况,比如密码管理器、广告拦截插件可能会修改页面元素的焦点行为。试试在无痕模式下打开页面,如果问题消失了,就逐个禁用扩展排查。
内容的提问来源于stack exchange,提问作者Tacohojo

