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
/>
);
};
CodePudding user response:
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}
/>