【发布时间】:2021-05-27 17:10:27
【问题描述】:
我将一份表格分成两部分。第一种形式采用 firstName、lastName 和 profilePhoto。第二个表单接受电子邮件、密码、confirmPassword 等。当用户填写第一个表单并单击下一步按钮时,第一个表单中的值不会停留在表单状态。如 react-hook-form 文档中所述,我已将 shouldUnregister 设置为 false。但这似乎并不能解决我的问题。
//hooks.ts
const defaultRegisterValues = {
email: "",
password: "",
confirmPassword: "",
firstName: "",
lastName: "",
institution: "",
regNo: "",
department: "",
profilePhoto: "",
};
const {
register,
handleSubmit,
watch,
getValues,
formState: { errors: formErrors },
} = useForm<RegisterFormInputs>({
defaultValues: defaultRegisterValues,
shouldFocusError: true,
shouldUnregister: false,
});
const watchFields = watch();
console.log("fields", watchFields);
const emailRegister = register("email", {
required: true,
minLength: 5,
maxLength: 50,
});
const passwordRegister = register("password", {
required: true,
minLength: 5,
maxLength: 50,
});
const confirmPasswordRegister = register("confirmPassword", {
required: true,
minLength: 5,
maxLength: 50,
validate: value => value === watch("password") || "Passwords do not match",
});
const firstNameRegister = register("firstName", {
required: true,
maxLength: 50,
});
const lastNameRegister = register("lastName", {
maxLength: 50,
});
const institutionRegister = register("institution", {
required: true,
});
const departmentRegister = register("department", {
required: true,
});
const regNoRegister = register("regNo", {
required: true,
minLength: 5,
maxLength: 15,
});
const profilePhotoRegister = register("profilePhoto", {
required: true,
});
const onSubmit = handleSubmit((data: RegisterFormInputs) => {
console.log("submitting");
console.log("Creating user...", data);
});
//FirstForm.tsx
const { firstNameRegister, lastNameRegister, profilePhotoRegister, errors, getValues } = useRegister();
return (
<Slide
direction="left"
in={!isOpen}
style={{ zIndex: 5, width: "30vw", position: "relative" }}
unmountOnExit={true}
>
<FormControl isInvalid={!!errors.profilePhoto} isRequired>
<FileUpload accept={"image/*"} multiple={false} register={profilePhotoRegister}>
<IconButton
aria-label="Profile Photo"
icon={<AvatarPlaceholder boxSize={120} />}
isRound
boxSize={120}
style={{ margin: "0 auto" }}
/>
</FileUpload>
<FormErrorMessage>{errors.profilePhoto && errors.profilePhoto}</FormErrorMessage>
</FormControl>
<RegisterFieldContainer>
<FormControl id="firstName" isInvalid={!!errors.firstName}>
<FormLabel>First Name</FormLabel>
<Input
name={firstNameRegister?.name}
type="text"
ref={firstNameRegister?.ref}
onChange={firstNameRegister?.onChange}
defaultValue={getValues("firstName")}
/>
<FormErrorMessage>{errors.firstName}</FormErrorMessage>
</FormControl>
<FormControl id="lastName" isInvalid={!!errors.lastName}>
<FormLabel>Last Name</FormLabel>
<Input
name={lastNameRegister?.name}
type="text"
ref={lastNameRegister?.ref}
onChange={lastNameRegister?.onChange}
defaultValue={getValues("lastName")}
/>
<FormErrorMessage>{errors.lastName}</FormErrorMessage>
</FormControl>
</RegisterFieldContainer>
<Center>
<IconButton
variant="solid"
aria-label="forward"
icon={<ArrowForwardIcon boxSize={10} />}
isRound
boxSize={16}
marginTop={10}
onClick={onToggle}
/>
</Center>
</Slide>
// SecondForm.tsx
const {
emailRegister,
passwordRegister,
confirmPasswordRegister,
regNoRegister,
institutionRegister,
departmentRegister,
errors,
} = useRegister();
return (
<Slide
in={isOpen}
unmountOnExit={true}
direction="right"
style={{ zIndex: zIdxValue, width: "30vw", position: "relative" }}
>
<RegisterFieldSubContainer>
<FormControl id="email">
<FormLabel>Email</FormLabel>
<Input name={emailRegister?.name} type="email" ref={emailRegister?.ref} onChange={emailRegister?.onChange} />
{errors.email && <FormErrorMessage>{errors.email}</FormErrorMessage>}
</FormControl>
<FormControl id="regNo">
<FormLabel>Registration Number</FormLabel>
<Input name={regNoRegister?.name} type="text" ref={regNoRegister?.ref} onChange={regNoRegister?.onChange} />
{errors.regNo && <FormErrorMessage>{errors.regNo}</FormErrorMessage>}
</FormControl>
</RegisterFieldSubContainer>
<RegisterFieldSubContainer>
<FormControl id="password">
<FormLabel>Password</FormLabel>
<Input
name={passwordRegister?.name}
type="password"
ref={passwordRegister?.ref}
onChange={passwordRegister?.onChange}
/>
{errors.password && <FormErrorMessage>{errors.password}</FormErrorMessage>}
</FormControl>
<FormControl id="confirmPassword">
<FormLabel>Confirm Password</FormLabel>
<Input
name={confirmPasswordRegister?.name}
type="password"
ref={confirmPasswordRegister?.ref}
onChange={confirmPasswordRegister?.onChange}
/>
{errors.confirmPassword && <FormErrorMessage>{errors.confirmPassword}</FormErrorMessage>}
</FormControl>
</RegisterFieldSubContainer>
<RegisterFieldSubContainer>
<FormControl id="institution">
<FormLabel>Institution</FormLabel>
<Input
name={institutionRegister?.name}
type="text"
ref={institutionRegister?.ref}
onChange={institutionRegister?.onChange}
/>
{errors.institution && <FormErrorMessage>{errors.institution}</FormErrorMessage>}
</FormControl>
<FormControl id="department">
<FormLabel>Department</FormLabel>
<Input
name={departmentRegister?.name}
type="text"
ref={departmentRegister?.ref}
onChange={departmentRegister?.onChange}
/>
{errors.department && <FormErrorMessage>{errors.department}</FormErrorMessage>}
</FormControl>
</RegisterFieldSubContainer>
<Flex flexDirection="row" alignItems="baseline" width="100%" justifyContent="space-between">
<Button variant="link" onClick={onToggle} marginTop="2em">
Back
</Button>
<RegisterButton type="submit" variant="solid" marginTop="2em" width="45%">
Register
</RegisterButton>
</Flex>
</Slide>
//index.tsx (the one that renders both forms
const { handleSubmit } = useRegister();
return (
<RegisterContainer>
<RegisterFormContainer>
<Heading>Register</Heading>
<RegisterForm onSubmit={handleSubmit}>
<FirstForm isOpen={isOpen} onToggle={onToggle} />
<SecondForm isOpen={isOpen} onToggle={onToggle} />
</RegisterForm>
{!isOpen && <Link href="/login">Already have an account? Login</Link>}
</RegisterFormContainer>
</RegisterContainer>
);
【问题讨论】:
标签: javascript reactjs typescript react-hook-form