【发布时间】:2021-04-15 07:11:19
【问题描述】:
我遇到了麻烦,需要资深人士的帮助。 当用户单击 Formik 表单内的链接时,我需要呈现模式组件。但是那个表单已经是一个组件,所以我试图在另一个组件内渲染一个组件,该组件位于一个更大的组件内。但不工作。 模式或仍然永远打开(从加载页面)或根本没有加载。
这是我尝试过的代码。
表格:
// Dependencies
// $FlowExpectedError[cannot-resolve-module] */
import { useRouter } from "next/router";
// $FlowExpectedError[cannot-resolve-module] */
import { AnimatePresence, motion } from "framer-motion";
// $FlowExpectedError[cannot-resolve-module] */
import { setCookie } from "nookies";
import { Modal } from "../components/Common";
// Components
// $FlowExpectedError[cannot-resolve-module] */
import { ErrorMessage, Formik, Field, Form } from "formik";
import {
Button,
Label,
FormField,
FormCheckbox,
HeadLogo,
} from "../components/Common";
// Helpers
import { axiosRequest } from "../helpers/axiosRequest";
import React, { useState } from "react";
import literals from "../utils/literals";
const GENDERS = [
{
label: "Female",
val: "female",
},
{
label: "Male",
val: "male",
},
{
label: "Other",
val: "other",
},
];
const ModalCloseButton = ({ closeCallback }) => (
<div>
<button
type="button"
className="float-right p-5 focus:outline-none"
onClick={closeCallback}
>
{/* $FlowExpectedError[cannot-resolve-name] */}
<img
src="/icons/close.svg"
alt="Close icon"
className="float-right w-4"
/>
</button>
</div>
);
const TermsModal = ({ closeCallback }) => (
// $FlowExpectedError[cannot-resolve-name]
<>
<ModalCloseButton closeCallback={closeCallback} />
<span className="px-5 pb-5 text-lg font-bold leading-none">
{literals.SEND_TO_FRIEND}
</span>
<div className="botton justify-center">
<Button label={literals.ACCEPT} onClick={closeCallback} style="icon" />
</div>
</>
);
const SignupForm = ({
validateForm,
submitForm,
setCheckedGender,
checkedGender,
openModal,
cancelModal,
}) => (
<Formik
initialValues={{
name: "",
surnames: "",
email: "",
phone: "",
birthDate: "",
gender: "",
password: "",
terms: false,
}}
validate={validateForm}
onSubmit={submitForm}
>
{({ isSubmitting, setFieldValue, values }) => {
function handleGenderSelection(value) {
setCheckedGender(value);
setFieldValue("gender", value);
}
return (
<Form className="flex flex-col w-full space-y-2">
{/* $FlowExpectedError[cannot-resolve-name] */}
<FormField
name="name"
inputType="text"
className="text-input-bis focus:outline-none"
inputPlaceholder={literals.NAME}
/>
<FormField
name="surnames"
inputType="text"
className="text-input-bis focus:outline-none"
inputPlaceholder={literals.SURNAME}
/>
<FormField
name="email"
inputType="email"
className="text-input-bis focus:outline-none"
inputPlaceholder={literals.EMAIL}
/>
<FormField
name="password"
inputType="password"
className="text-input-bis focus:outline-none"
inputPlaceholder={literals.PASSWORD}
/>
<FormField
name="phone"
inputType="tel"
className="text-input-bis focus:outline-none"
inputPlaceholder={literals.PHONE_NUMBER}
/>
<FormField
name="birthDate"
inputType="date"
className="text-input-bis focus:outline-none"
inputPlaceholder={literals.BIRTHDATE}
/>
<div role="group" className="signup-radio">
{GENDERS.map((gender) => {
return (
<label
key={gender.val}
className={`
px-4 pt-3 pb-2 mr-2 border border-white rounded-gender leading-snug transition-colors duration-200
${
checkedGender && gender.val === checkedGender
? "bg-lightBlue"
: "transparent"
}
`}
>
<Field
type="radio"
name="gender"
value={gender.val}
checked={checkedGender === gender.val}
onChange={() => {
handleGenderSelection(gender.val);
}}
/>
<p className="text-sm text-white uppercase">{gender.label}</p>
</label>
);
})}
<ErrorMessage
name="gender"
component="div"
className="error-message"
/>
</div>
<div className="flex flex-row items-center justify-start">
<FormCheckbox
label={
<p className="ml-2 text-sm text-lightBlue">
{literals.ACCEPT_THE}
<a
href="#"
className="text-white underline"
onClick={cancelModal()}
>
{literals.TERMS_TITLE}
</a>
</p>
}
name="terms"
callback={() => setFieldValue("terms", !values.terms)}
callbackValue={!values.terms}
fillColor="lightBlue"
value={values.terms}
marginBottom="4"
/>
</div>
<div className="pb-4">
<Button type="submit" label={literals.SIGNUP} />
</div>
{/* <div className="flex flex-col items-stretch justify-start h-vh-5 flex-1 px-5 pb-5">
<div className="flex flex-col flex-1 mt-12">
<a
href={literals.GLOBAL_TERMS}
target="_blank"
className="text-xl font-bold leading-tight"
>
<u>Download</u> our Terms & Conditions
</a>
</div>
<div className="botton justify-center">
<Button
label={literals.ACCEPT}
onClick={() => setShowModal(false)}
style="icon"
/>
</div>
</div>
</Modal>
</AnimatePresence> */}
</Form>
);
}}
</Formik>
);
function Signup(): React$Node {
const [checkedGender, setCheckedGender] = useState();
const [showModal, setShowModal] = useState();
function cancelModal() {
console.log("fechar");
setShowModal(false);
}
function openModal() {
console.log("abrir");
setShowModal(true);
}
// TODO: Review validation
function validateForm(values) {
const errors = {};
if (!values.name) {
errors.name = "Required";
}
if (!values.surnames) {
errors.surnames = "Required";
}
if (!values.email) {
errors.email = "Required";
}
if (!values.password) {
errors.password = "Required";
}
if (!values.phone) {
errors.phone = "Required";
}
if (!values.birthDate) {
errors.birthDate = "Required";
}
if (!values.gender) {
errors.gender = "Required";
}
if (!values.terms) {
errors.terms = "Required";
}
return errors;
}
async function submitForm(body, { setErrors }) {
const res = await axiosRequest({
method: "POST",
url: "/auth/register",
data: body,
});
if (res?.accessCookie) {
const accessCookie = res.accessCookie;
const refreshCookie = res.refreshCookie;
setCookie(null, "accessToken", accessCookie.token, accessCookie.options);
setCookie(
null,
"refreshToken",
refreshCookie.token,
refreshCookie.options
);
router.reload();
} else {
const errorData = res?.error?.response?.data || {};
setErrors({ [errorData.field]: errorData.error });
}
}
return (
<motion.div
className="flex flex-col min-h-full"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<HeadLogo />
<div className="grid w-full min-h-screen grid-cols-4 gap-4 px-5 rounded-background bg-purple">
<div className="col-span-3 col-start-1 text-white mt-28">
<h1 className="w-full mb-3 font-bold leading-none text-40px">
{literals.SIGNUP_TITLE}
</h1>
<p className="w-full text-base font-light">
{literals.SIGNUP_SUBTITLE}
</p>
</div>
<div className="flex-col w-full col-span-4">
{/* $FlowExpectedError[cannot-resolve-name] */}
<SignupForm
validateForm={validateForm}
submitForm={submitForm}
setCheckedGender={setCheckedGender}
checkedGender={checkedGender}
openModal={openModal}
cancelModal={cancelModal}
/>
<Modal cancelCallback={cancelModal} closeCallback={cancelModal}>
<TermsModal closeCallback={cancelModal} />
</Modal>
</div>
</div>
</motion.div>
);
}
export default Signup;
这是组件模态:
// @flow
import { Button } from "./Button";
// $FlowExpectedError[cannot-resolve-module]
import { motion } from "framer-motion";
type Props = {
children: any,
cancelCallback?: function,
closeCallback: function,
}
export const Modal = ({
children,
cancelCallback,
closeCallback,
}: Props): React$Node => {
return (
// $FlowExpectedError
<motion.div
className="fixed inset-0 z-50 px-5 py-16 overflow-hidden bg-darkBlue bg-opacity-90 text-darkBlue"
onClick={cancelCallback || closeCallback}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
{/* $FlowExpectedError */}
<motion.div
className="flex flex-col items-stretch justify-start max-h-full overflow-y-auto bg-white rounded-card"
onClick={e => e.stopPropagation()}
initial={{ y: 64, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
exit={{ y: 0, opacity: 0 }}
transition={{
type: "spring",
duration: 0.5,
bounce: 0,
}}
>
{children}
</motion.div>
</motion.div>
);
};
【问题讨论】:
标签: javascript reactjs next.js formik