im getting some error saying cant destructure the property ‘name’ of e.target undefined I will be grateful for any help. unable to assign any value in the input field. I need to sign up as a client, but when I enter the value they can’t assign, what can i do ?
export const Form = ({ sx, onSubmit }) => { const [form, setForm] = useState({ email: {value: "", error: null}, password: {value: "", error: null}, role: roles.client, }); const [errors, setErrors] = useState({ email: null, password: null, role: null, }); const handleChange = (e) => { const { name, value } = e.target; setForm({ ...form, [name]: value }); // authValidators[name]({ // value, // cb: (error) => setErrors((prev) => ({ ...prev, ...error })), // }); }; const handleSubmit = () => { // for (let key in form) { // if (key === "role") continue; // // authValidators[key]({ // // value: form[key], // // cb: (error) => setErrors((prev) => ({ ...prev, ...error })), // // }); // } for (let key in form) { if (form[key].length === 0 || errors[key]) { return; } } onSubmit(form); }; return ( <Box sx={sx.root}> <EmailInput sx={sx.input} valueObj={form.email} error={errors.email !== null} errorMessage={errors.email} onChange={handleChange} /> <PasswordInput sx={sx.input} valueObj={form.password} error={errors.password !== null} errorMessage={errors.password} onChange={handleChange} /> <GroupToggleField sx={sx.toggleButton} value={form.role} onChange={(value) => setForm({ ...form, role: value })} options={options} /> <Button sx={sx.button} onClick={handleSubmit}> Sign In </Button> </Box> ); }; const options = [ { value: roles.client, title: "Client" }, { value: roles.member, title: "Crew Member" }, ];
i also writen a code for email and password separatly this is my email code:
export const EmailInput = ({ fieldname, label, placeHolder, valueObj, onChange, }) => { const handleChange = ({ target: { value } }) => { let error = null; const re = /S+@S+.S+/; if (!re.test(value)) { error = `${label} proper email address`; } if (value.length === 0) { error = `${label} field cannot be empty`; } onChange(fieldname, { value, error }); }; return ( <TextField onFocus={handleChange} onChange={handleChange} value={valueObj.value} error={valueObj.error !== null} helperText={valueObj.error} label={label} placeholder={placeHolder} margin="normal" size="small" fullWidth /> ); };
this is my password code:
export const PasswordInput = ({ valueObj, onChange }) => { const [showPassword, setShowPassword] = useState(false); const handleShowPassword = () => setShowPassword((prev) => !prev); const handleChange = ({ target: { name, value } }) => { let error = null; if (value.length <= 5) { error = "Password must be minimum 6 characters"; } if (value.length === 0) { error = "Password field cannot be empty"; } onChange(name, { value, error }); }; const toggle = ( <InputAdornment position="end"> <IconButton onClick={handleShowPassword} edge="end"> {showPassword ? ( <VisibilityOff fontSize="small" /> ) : ( <Visibility fontSize="small" /> )} </IconButton> </InputAdornment> ); return ( <TextField onFocus={handleChange} onChange={handleChange} value={valueObj.value} error={valueObj.error !== null} helperText={valueObj.error} InputProps={{ endAdornment: toggle }} type={showPassword ? "text" : "password"} label="Password" name="password" margin="normal" size="small" fullWidth /> ); };
Advertisement
Answer
There’s a lot here, so I’m taking a quick first pass.
Let’s look at your EmailInput
component. It takes onChange
as a prop. When the internal TextField
component experiences a "change"
event, it calls the internal function EmailInput > handleChange
; that in turn calls whatever function was passed in the onChange
prop to the EmailInput
component.
So in EmailInput
, this line is calling whatever function was passed to onChange
as a prop:
onChange(fieldname, { value, error });
So the first argument is fieldname
, which is probably a String. The second argument is an Object with properties value
and error
. What function is being called? Let’s look at your Form
component:
const handleChange = (e) => { const { name, value } = e.target; setForm({ ...form, [name]: value }); // authValidators[name]({ // value, // cb: (error) => setErrors((prev) => ({ ...prev, ...error })), // }); }; // ... Skip a few lines... <EmailInput sx={sx.input} valueObj={form.email} error={errors.email !== null} errorMessage={errors.email} onChange={handleChange} />
So you see, handleChange
is the actual function that we call inside EmailComponent
when we call onChange
. Right now, handleChange
only takes one argument, “e
“, though as you can see above we are passing it two. Furthermore, it seems to expect e
to be an Object with a target
property, but it is actually a String, fieldname
.
Therefore, the handleChange
function inside the Form
component should look something like this:
const handleChange = (fieldName, { value }) => { setForm({ ...form, [fieldName]: value }); };
You might run into a problem because I don’t see you providing the fieldname
prop to EmailInput
; maybe add something like this here:
<EmailInput fieldname="email" // Add this line sx={sx.input} valueObj={form.email} error={errors.email !== null} errorMessage={errors.email} onChange={handleChange} />