I am facing issue when customizing MUI component with styled
library. The text field loses focus on typing my character in it. It works fine if I am using inline sx based styling. Perhaps I am calling it incorrectly. Any help will be highly appreciated.
Simple form page:
const initialValues = {
vehicle: "",
mobile: "",
email: "",
name: "",
address: "",
alt_mobile: "",
};
const { values, setValues, handleChange } = useForm(initialValues);
return (
<Box border={1}>
<Grid container>
<Grid item xs={6}>
<StyledField
value={values.vehicle}
onChange={handleChange}
variant="outlined"
label="Vehicle No"
name="vehicle"
key="vehicle"
/>
</Grid>
</Grid>
</Box>
);
useform.js
import { React, useState } from 'react'
export function useForm(initialValues) {
const [values, setvalues] = useState(initialValues);
const handleChange = e => {
const { name, value } = e.target
setvalues({
...values,
[name]: value
})
}
return {
values,
setvalues,
handleChange,
}
}
finally my custom text field component:
export default function CustomField(props) {
const SyledField = styled(TextField)(({ theme }) => ({
width: "70%",
margin: theme.spacing(1),
}));
const { name, label, value, onChange, ...others } = props
return (
<SyledField
variant="outlined"
label={label}
name={name}
onChange={onChange}
value={value}
{...others}
/>
);
}
If I change the custom custom to use sx
based styling, it works fine:
export default function CustomField(props) {
const { name, label, value, onChange, ...others } = props
return (
<TextField
sx={{ width: "70%", margin: "8px" }}
variant="outlined"
label={label}
name={name}
onChange={onChange}
value={value}
{...others}
/>
);
}
I have gone through many forums and tried using keys, calling JSX as function but it does not seem to help. It seems React is re-loading the component each time onChange event triggered. Any suggestion?
The styled
function generates a new component whenever called. When you call it inside CustomField
, it generates a new component on each render. Move it out of CustomField
.
const SyledField = styled(TextField)(({ theme }) => ({
width: "70%",
margin: theme.spacing(1),
}));
export default function CustomField(props) {
const { name, label, value, onChange, ...others } = props
return (
<SyledField
variant="outlined"
label={label}
name={name}
onChange={onChange}
value={value}
{...others}
/>
);
}