Material UI TextField每输入一个字符就失焦仅接受单个字母问题求助
问题根因
该问题的核心是CssTextField被定义在函数组件内部,每次你输入内容触发setForm更新组件状态时,styled()方法都会生成一个全新的组件实例,React会销毁旧的TextField实例并挂载新实例,因此会出现输入一个字符就自动失焦的问题。旧版本MUI对styled组件重复创建的兼容性处理逻辑不同,所以之前运行正常。
解决方案
- 方法1:将styled组件定义移到函数组件外部(推荐)
把CssTextField的定义代码放到登录组件函数外,全局仅初始化一次,即可避免重复挂载问题,代码示例:
// 组件函数外全局定义 const CssTextField = styled(TextField)({ "& label.Mui-focused": { color: "#71716A", }, "& .MuiInput-underline:after": { borderBottomColor: "#71716A", }, "& .MuiOutlinedInput-root": { "&.Mui-focused fieldset": { borderColor: "#71716A", }, }, }); // 登录组件逻辑 const Login = () => { const [form, setForm] = useState({ name: "", password: "" }); const handleChange = (e) => { setForm({ ...form, [e.target.name]: e.target.value }); }; // 剩余渲染逻辑... }
- 方法2:若确实需要在组件内部定义(比如需要用组件内部参数动态调整样式),用
useMemo包裹styled组件的创建过程,避免不必要的重生成:
const Login = () => { const [form, setForm] = useState({ name: "", password: "" }); // 用useMemo缓存styled组件实例 const CssTextField = useMemo(() => styled(TextField)({ "& label.Mui-focused": { color: "#71716A", }, "& .MuiInput-underline:after": { borderBottomColor: "#71716A", }, "& .MuiOutlinedInput-root": { "&.Mui-focused fieldset": { borderColor: "#71716A", }, }, }), []); // 若有动态样式参数,将参数放到依赖数组中即可 const handleChange = (e) => { setForm({ ...form, [e.target.name]: e.target.value }); }; // 剩余渲染逻辑... }
冗余代码优化
你当前写的handleChange中的e.preventDefault()可以删除,input输入的onChange事件没有需要阻止的默认行为,这段代码无实际作用。
内容的提问来源于stack exchange,提问作者Thanh
相关产品推荐
相关产品推荐

