英文:
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;
我也尝试过以下链接的解决方案,但没有帮助:
- 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
以及其他类似的问题。
英文:
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) => {
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;
I also Tried-
https://stackoverflow.com/questions/22573494/react-js-input-losing-focus-when-rerendering?rq=2
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
/>
在你的代码中,你需要将StyledTextField
和FormContainer
移到组件外部,以避免引起不必要的重新渲染。
例如:
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:
<StyledTextField
label="First Name"
name="firstName" // this line (you are using "firstname")
value="{formData.firstName}"
onChange="{handleChangeForm}"
key="firstName"
size="medium"
required
fullWidth
/>
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("form")(({ theme }) => ({
/* ... */
}));
const StyledTextField = styled(TextField)(() => ({
/* ... */
}));
const Registration = (props: any) => {
/* ... */
};
export default Registration;
答案2
得分: 0
这里有两个问题:
首先,你在每次渲染时都重新创建了你的样式组件 FormContainer
和 StyledTextField
,导致它们在每次重新渲染时失去焦点。可以通过将它们移到 Registration
组件的外部来解决这个问题。
其次,你在 StyledTextField
的 name
属性中有一个拼写错误。尝试使用 firstName
(首字母大写的 "N")而不是 firstname
。
在JavaScript中,标识符是大小写敏感的。这意味着 firstName
和 firstname
将是不同的属性。在这里,你设置了 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论