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

MUI TextField输入时状态不更新,组件重渲染丢失状态求助

React MUI TextField输入框值无法更新、输入后失焦问题解决

问题描述

使用React + MUI开发时,TextField输入框在输入首个字符后触发组件重渲染,丢失输入状态且无法继续更新值。曾尝试用Box替代Grid、参考相关方案均未解决。

问题根源及修复方案

1. 内部定义Styled组件导致重复创建

FormContainer和StyledTextField定义在Registration组件函数内部,每次组件重渲染时都会重新生成新的组件类型,React会卸载旧组件并挂载新组件,直接导致输入框失焦、状态丢失。

修复:将Styled组件移到组件外部定义:

// 移到Registration组件外部
const FormContainer = styled("form")(({ theme }) => ({
  maxWidth: 700,
  [theme.breakpoints.down(theme.breakpoints.values.sm)]: {
    maxWidth: 300
  },
  [theme.breakpoints.up(theme.breakpoints.values.md)]: {
    maxWidth: 650
  }
}));

const StyledTextField = styled(TextField)(() => ({
  "& .MuiFormLabel-asterisk": {
    color: "red"
  },
  '& label.Mui-focused': {
    color: '#96A8AE', //Dark Grey as per SCM
  },
  '& .MuiOutlinedInput-root': {
    '&.Mui-focused fieldset': {
      borderColor: '#96A8AE',
    },
  },
}));

const Registration = (props: any) => {
  // 组件内部逻辑...
};

2. TextField的name属性与state字段不匹配

TextField的name属性为firstname(小写n),但state中对应的字段是firstName(大写N),导致handleChangeForm无法正确更新state,输入值无法同步。

修复:将TextField的name改为firstName:

<StyledTextField
  label="First Name"
  name="firstName" // 修正为与state字段一致
  value={formData.firstName}
  onChange={handleChangeForm}
  key="firstName"                                    
  size='medium'
  required
  fullWidth
/>

3. Grid组件嵌套属性错误

内部的Grid container额外添加了item属性,属于无效嵌套,可能影响组件渲染逻辑。

修复:移除该Grid的item属性:

<Grid container className='details__form' columnSpacing={{ xs: 2, sm: 2, md: 2 }}>
  <Grid item xs={6} md={6} lg={6} xl={6}>
    {/* TextField */}
  </Grid>
</Grid>

修改后的完整代码

import React, { useState, ChangeEvent } from 'react';
import { Grid, TextField } from '@mui/material';
import { styled } from '@mui/material/styles';
import axios from 'axios';
import Loader from './Loader'; // 假设Loader是你的自定义组件

const FormContainer = styled("form")(({ theme }) => ({
  maxWidth: 700,
  [theme.breakpoints.down(theme.breakpoints.values.sm)]: {
    maxWidth: 300
  },
  [theme.breakpoints.up(theme.breakpoints.values.md)]: {
    maxWidth: 650
  }
}));

const StyledTextField = styled(TextField)(() => ({
  "& .MuiFormLabel-asterisk": {
    color: "red"
  },
  '& label.Mui-focused': {
    color: '#96A8AE', //Dark Grey as per SCM
  },
  '& .MuiOutlinedInput-root': {
    '&.Mui-focused fieldset': {
      borderColor: '#96A8AE',
    },
  },
}));

const Registration = (props: any) => {        
  const [loading, setLoading] = useState(false);
  const [successAlert, setSuccessAlert] = useState(false);
  const [formData, setFormData] = useState({
    firstName: '',
  });

  const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    submitRegister();
  };

  const submitRegister = async () => {
    setLoading(true);
    try {
      const response = await axios.post('example.com/create/user', formData);
      console.log(response.data.code);
      if (response.data.code === 200) {
        setSuccessAlert(true);
      }
    } catch (error) {
      console.log(error);
    } finally {
      setLoading(false);
    }
  };

  const handleChangeForm = (e: ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setFormData((prevFormData) => ({
      ...prevFormData,
      [name]: value
    }));
  };

  return (
    <Grid container className="registration__container" spacing={2}>
      <Grid item xs={7} md={7} lg={7} xl={7}>
        <Grid className='left'>
          // some code here
        </Grid>
        {loading && <Loader />}
      </Grid>
      <Grid item xs={5} md={5} lg={5} xl={5} className='registration__form' key="regis-form">
        <FormContainer onSubmit={handleSubmit}>
          <Grid container className='details__form' columnSpacing={{ xs: 2, sm: 2, md: 2 }}>
            <Grid item xs={6} md={6} lg={6} xl={6}>
              <StyledTextField
                label="First Name"
                name="firstName"
                value={formData.firstName}
                onChange={handleChangeForm}
                key="firstName"                                    
                size='medium'
                required
                fullWidth
              />
            </Grid>
          </Grid>
          <Grid item xs={12} className="submitbtn__wrapper">
            <button type="submit">Register</button>
          </Grid>
        </FormContainer>
      </Grid>
    </Grid>
  );
};

export default Registration;

内容的提问来源于stack exchange,提问作者C P Verma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 01:12:34