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

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

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

问题

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

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

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

以下是我的代码:

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)
        axios.post('example.com/create/user', formData)
            .then(response => {
                console.log(response.data.code)
                if (response.data.code === 200) {
                    setSuccessAlert(true)
                    setLoading(false)
                }
            })
            .catch(error => {
                console.log(error)

            })

    }

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

    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',
            },
        },

    }));

    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 item 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;

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

英文:

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 :

const Registration = (props: any) =&gt; {       
const [loading, setLoading] = useState(false);
const [successAlert, setSuccessAlert]=useState(false)
const [formData, setFormData] = useState({
firstName:&#39;&#39;,
})
const handleSubmit = (event: React.FormEvent&lt;HTMLFormElement&gt;) =&gt; {
event.preventDefault();
submitRegister()
};
const submitRegister = async()=&gt;{
setLoading(true)
axios.post(&#39;example.com/create/user&#39;,formData)
.then(response =&gt;{
console.log(response.data.code)
if(response.data.code ===200){
setSuccessAlert(true)
setLoading(false)
}
})
.catch(error =&gt;{
console.log(error)
})
}  
const handleChangeForm=(e:ChangeEvent&lt;HTMLInputElement&gt;)=&gt;{
const{name ,value }= e.target;
setFormData((prevFormData)=&gt;({
...prevFormData,
[name]:value
}));
};
const FormContainer = styled(&quot;form&quot;)(({ theme }) =&gt; ({
maxWidth: 700,
[theme.breakpoints.down(theme.breakpoints.values.sm)]: {
maxWidth: 300
},
[theme.breakpoints.up(theme.breakpoints.values.md)]: {
maxWidth: 650
}
}));
const StyledTextField = styled(TextField)(() =&gt; ({
&quot;&amp; .MuiFormLabel-asterisk&quot;: {
color: &quot;red&quot;
},
&#39;&amp; label.Mui-focused&#39;: {
color: &#39;#96A8AE&#39;, //Dark Grey as per SCM
},
&#39;&amp; .MuiOutlinedInput-root&#39;: {
&#39;&amp;.Mui-focused fieldset&#39;: {
borderColor: &#39;#96A8AE&#39;,
},
},
}));
return (
&lt;Grid container className=&quot;registration__container&quot; spacing={2}&gt;
&lt;Grid item xs={7} md={7} lg={7} xl={7}&gt;
&lt;Grid className=&#39;left&#39;&gt;
// some code here
&lt;/Grid&gt;
{loading &amp;&amp;&lt;Loader /&gt; }
&lt;/Grid&gt;
&lt;Grid item xs={5} md={5} lg={5} xl={5} className=&#39;registration__form&#39; key=&quot;regis-form&quot;&gt;
&lt;FormContainer onSubmit={handleSubmit}&gt;
&lt;Grid item container className=&#39;details__form&#39; columnSpacing={{ xs: 2, sm: 2, md: 2 }}&gt;
&lt;Grid item xs={6} md={6} lg={6} xl={6}&gt;
&lt;StyledTextField
label=&quot;First Name&quot;
name=&quot;firstname&quot;
value={formData.firstName}
onChange={handleChangeForm}
key=&quot;firstName&quot;                                    
size=&#39;medium&#39;
required
fullWidth
/&gt;
&lt;/Grid&gt;
&lt;/Grid&gt;
&lt;Grid item xs={12} className=&quot;submitbtn__wrapper&quot;&gt;
&lt;button type=&quot;submit&quot;&gt;Register&lt;/button&gt;
&lt;/Grid&gt;
&lt;/FormContainer&gt;
&lt;/Grid&gt;
&lt;/Grid&gt;
);
};
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属性。

例如:

<StyledTextField
  label="First Name"
  name="firstName"   // 这一行你使用了 "firstname")
  value={formData.firstName}
  onChange={handleChangeForm}
  key="firstName"
  size="medium"
  required
  fullWidth
/>

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

例如:

const FormContainer = styled("form")(({ theme }) => ({
  /* ... */
}));

const StyledTextField = styled(TextField)(() => ({
  /* ... */
}));

const Registration = (props: any) => {
  /* ... */
};

export default Registration;
英文:

I think you are passing name prop in TextField incorrectly.

For example:

&lt;StyledTextField
label=&quot;First Name&quot;
name=&quot;firstName&quot;   // this line (you are using &quot;firstname&quot;)
value=&quot;{formData.firstName}&quot;
onChange=&quot;{handleChangeForm}&quot;
key=&quot;firstName&quot;
size=&quot;medium&quot;
required
fullWidth
/&gt;

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

For example:

const FormContainer = styled(&quot;form&quot;)(({ theme }) =&gt; ({
/* ... */
}));
const StyledTextField = styled(TextField)(() =&gt; ({
/* ... */
}));
const Registration = (props: any) =&gt; {
/* ... */
};
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:

确定