为什么在输入MUI文本字段时输入字段状态不会改变?

huangapple go评论106阅读模式
英文:

why does the input field state is not changing while typing in textField MUI

问题

在我的 react.js 组件中,当我尝试在 textField 中输入任何内容时,它没有更新。

我尝试使用调试器,发现当第一个字符输入时,组件重新渲染,因此失去了它的先前状态,看起来 textField 的值没有更新。

之前,当我使用 MUI Box 而不是 Grid 时,它正常工作,但现在即使删除 Grid 也不起作用。
许多人都提出了相同的问题,我查看了他们提供的解决方案,但没有运气。

以下是我的代码:

  1. const Registration = (props: any) => {
  2. const [loading, setLoading] = useState(false);
  3. const [successAlert, setSuccessAlert] = useState(false)
  4. const [formData, setFormData] = useState({
  5. firstName: '',
  6. })
  7. const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
  8. event.preventDefault();
  9. submitRegister()
  10. };
  11. const submitRegister = async () => {
  12. setLoading(true)
  13. axios.post('example.com/create/user', formData)
  14. .then(response => {
  15. console.log(response.data.code)
  16. if (response.data.code === 200) {
  17. setSuccessAlert(true)
  18. setLoading(false)
  19. }
  20. })
  21. .catch(error => {
  22. console.log(error)
  23. })
  24. }
  25. const handleChangeForm = (e: ChangeEvent<HTMLInputElement>) => {
  26. const { name, value } = e.target;
  27. setFormData((prevFormData) => ({
  28. ...prevFormData,
  29. [name]: value
  30. }));
  31. };
  32. const FormContainer = styled("form")(({ theme }) => ({
  33. maxWidth: 700,
  34. [theme.breakpoints.down(theme.breakpoints.values.sm)]: {
  35. maxWidth: 300
  36. },
  37. [theme.breakpoints.up(theme.breakpoints.values.md)]: {
  38. maxWidth: 650
  39. }
  40. }));
  41. const StyledTextField = styled(TextField)(() => ({
  42. "& .MuiFormLabel-asterisk": {
  43. color: "red"
  44. },
  45. '& label.Mui-focused': {
  46. color: '#96A8AE', //Dark Grey as per SCM
  47. },
  48. '& .MuiOutlinedInput-root': {
  49. '&.Mui-focused fieldset': {
  50. borderColor: '#96A8AE',
  51. },
  52. },
  53. }));
  54. return (
  55. <Grid container className="registration__container" spacing={2}>
  56. <Grid item xs={7} md={7} lg={7} xl={7}>
  57. <Grid className='left'>
  58. // some code here
  59. </Grid>
  60. {loading && <Loader />}
  61. </Grid>
  62. <Grid item xs={5} md={5} lg={5} xl={5} className='registration__form' key="regis-form">
  63. <FormContainer onSubmit={handleSubmit}>
  64. <Grid item container className='details__form' columnSpacing={{ xs: 2, sm: 2, md: 2 }}>
  65. <Grid item xs={6} md={6} lg={6} xl={6}>
  66. <StyledTextField
  67. label="First Name"
  68. name="firstname"
  69. value={formData.firstName}
  70. onChange={handleChangeForm}
  71. key="firstName"
  72. size='medium'
  73. required
  74. fullWidth
  75. />
  76. </Grid>
  77. </Grid>
  78. <Grid item xs={12} className="submitbtn__wrapper">
  79. <button type="submit">Register</button>
  80. </Grid>
  81. </FormContainer>
  82. </Grid>
  83. </Grid>
  84. );
  85. };
  86. export default Registration;

我也尝试过以下链接的解决方案,但没有帮助:

英文:

In my react.js component, when i am trying to start type anything in textField, it is not updating .

I tried with debugger the i found -- when first character entered, component re-renderd so looses its prevous states and looks like textField value is not updating.

It was working fine earlier when i was using mui Box instead of Grid, but now removing Grid also is not working .
Same question asked by many people, i went through their provided solution but no luck.

Here is my code :

  1. const Registration = (props: any) =&gt; {
  2. const [loading, setLoading] = useState(false);
  3. const [successAlert, setSuccessAlert]=useState(false)
  4. const [formData, setFormData] = useState({
  5. firstName:&#39;&#39;,
  6. })
  7. const handleSubmit = (event: React.FormEvent&lt;HTMLFormElement&gt;) =&gt; {
  8. event.preventDefault();
  9. submitRegister()
  10. };
  11. const submitRegister = async()=&gt;{
  12. setLoading(true)
  13. axios.post(&#39;example.com/create/user&#39;,formData)
  14. .then(response =&gt;{
  15. console.log(response.data.code)
  16. if(response.data.code ===200){
  17. setSuccessAlert(true)
  18. setLoading(false)
  19. }
  20. })
  21. .catch(error =&gt;{
  22. console.log(error)
  23. })
  24. }
  25. const handleChangeForm=(e:ChangeEvent&lt;HTMLInputElement&gt;)=&gt;{
  26. const{name ,value }= e.target;
  27. setFormData((prevFormData)=&gt;({
  28. ...prevFormData,
  29. [name]:value
  30. }));
  31. };
  32. const FormContainer = styled(&quot;form&quot;)(({ theme }) =&gt; ({
  33. maxWidth: 700,
  34. [theme.breakpoints.down(theme.breakpoints.values.sm)]: {
  35. maxWidth: 300
  36. },
  37. [theme.breakpoints.up(theme.breakpoints.values.md)]: {
  38. maxWidth: 650
  39. }
  40. }));
  41. const StyledTextField = styled(TextField)(() =&gt; ({
  42. &quot;&amp; .MuiFormLabel-asterisk&quot;: {
  43. color: &quot;red&quot;
  44. },
  45. &#39;&amp; label.Mui-focused&#39;: {
  46. color: &#39;#96A8AE&#39;, //Dark Grey as per SCM
  47. },
  48. &#39;&amp; .MuiOutlinedInput-root&#39;: {
  49. &#39;&amp;.Mui-focused fieldset&#39;: {
  50. borderColor: &#39;#96A8AE&#39;,
  51. },
  52. },
  53. }));
  54. return (
  55. &lt;Grid container className=&quot;registration__container&quot; spacing={2}&gt;
  56. &lt;Grid item xs={7} md={7} lg={7} xl={7}&gt;
  57. &lt;Grid className=&#39;left&#39;&gt;
  58. // some code here
  59. &lt;/Grid&gt;
  60. {loading &amp;&amp;&lt;Loader /&gt; }
  61. &lt;/Grid&gt;
  62. &lt;Grid item xs={5} md={5} lg={5} xl={5} className=&#39;registration__form&#39; key=&quot;regis-form&quot;&gt;
  63. &lt;FormContainer onSubmit={handleSubmit}&gt;
  64. &lt;Grid item container className=&#39;details__form&#39; columnSpacing={{ xs: 2, sm: 2, md: 2 }}&gt;
  65. &lt;Grid item xs={6} md={6} lg={6} xl={6}&gt;
  66. &lt;StyledTextField
  67. label=&quot;First Name&quot;
  68. name=&quot;firstname&quot;
  69. value={formData.firstName}
  70. onChange={handleChangeForm}
  71. key=&quot;firstName&quot;
  72. size=&#39;medium&#39;
  73. required
  74. fullWidth
  75. /&gt;
  76. &lt;/Grid&gt;
  77. &lt;/Grid&gt;
  78. &lt;Grid item xs={12} className=&quot;submitbtn__wrapper&quot;&gt;
  79. &lt;button type=&quot;submit&quot;&gt;Register&lt;/button&gt;
  80. &lt;/Grid&gt;
  81. &lt;/FormContainer&gt;
  82. &lt;/Grid&gt;
  83. &lt;/Grid&gt;
  84. );
  85. };
  86. export default Registration;

I also Tried-
https://stackoverflow.com/questions/22573494/react-js-input-losing-focus-when-rerendering?rq=2

https://stackoverflow.com/questions/59715158/react-hooks-input-loses-focus-when-1-character-is-typed-in

https://stackoverflow.com/questions/42573017/in-react-es6-why-does-the-input-field-lose-focus-after-typing-a-character?rq=2
and other similar question , but did not help me.

答案1

得分: 1

我认为你在TextField中不正确地传递了name属性。

例如:

  1. <StyledTextField
  2. label="First Name"
  3. name="firstName" // 这一行你使用了 "firstname"
  4. value={formData.firstName}
  5. onChange={handleChangeForm}
  6. key="firstName"
  7. size="medium"
  8. required
  9. fullWidth
  10. />

在你的代码中,你需要将StyledTextFieldFormContainer移到组件外部,以避免引起不必要的重新渲染。

例如:

  1. const FormContainer = styled("form")(({ theme }) => ({
  2. /* ... */
  3. }));
  4. const StyledTextField = styled(TextField)(() => ({
  5. /* ... */
  6. }));
  7. const Registration = (props: any) => {
  8. /* ... */
  9. };
  10. export default Registration;
英文:

I think you are passing name prop in TextField incorrectly.

For example:

  1. &lt;StyledTextField
  2. label=&quot;First Name&quot;
  3. name=&quot;firstName&quot; // this line (you are using &quot;firstname&quot;)
  4. value=&quot;{formData.firstName}&quot;
  5. onChange=&quot;{handleChangeForm}&quot;
  6. key=&quot;firstName&quot;
  7. size=&quot;medium&quot;
  8. required
  9. fullWidth
  10. /&gt;

And in your code, you need to move StyledTextField and FormContainer outside of the component to avoid causing unnecessary re-rendering.

For example:

  1. const FormContainer = styled(&quot;form&quot;)(({ theme }) =&gt; ({
  2. /* ... */
  3. }));
  4. const StyledTextField = styled(TextField)(() =&gt; ({
  5. /* ... */
  6. }));
  7. const Registration = (props: any) =&gt; {
  8. /* ... */
  9. };
  10. export default Registration;

答案2

得分: 0

这里有两个问题:

首先,你在每次渲染时都重新创建了你的样式组件 FormContainerStyledTextField,导致它们在每次重新渲染时失去焦点。可以通过将它们移到 Registration 组件的外部来解决这个问题。

其次,你在 StyledTextFieldname 属性中有一个拼写错误。尝试使用 firstName(首字母大写的 "N")而不是 firstname

在JavaScript中,标识符是大小写敏感的。这意味着 firstNamefirstname 将是不同的属性。在这里,你设置了 formData 状态的 firstname 属性,但 StyledTextField 显示的值是 firstName,这不会被你的变更处理程序更新。

这是一个工作示例:https://stackblitz.com/edit/stackblitz-starters-tx9w4d?file=src%2FRegistration.tsx

英文:

There are 2 problems here:

First, you are recreating your styled components FormContainer and StyledTextField on each render, causing them to lose focus on each rerender. This can be fixed by moving both of them outside of the Registration component.

Second, you have a typo you have in the name property of your StyledTextField. Try firstName (with capital "N") instead.

In JavaScript, identifiers are case sensitive. That means that firstName and firstname will be different properties. Here, you are setting the firstname property of your formData state, but the value shown by the StyledTextField is firstName, which does not get updated by your change handler.

Here's a working example: https://stackblitz.com/edit/stackblitz-starters-tx9w4d?file=src%2FRegistration.tsx

huangapple
  • 本文由 发表于 2023年7月17日 16:55:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76702860.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定