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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:27:03