我有一个模态组件,可以有条件地呈现登录和注册表单,当我单击任何表单上的提交按钮时,即使调用不成功,模态也会关闭。 我在这个存储库中部署了我的代码。
这是我的模态:
"use client";
import { useEffect, useState } from "react";
import Box from "@mui/material/Box";
import Modal from "@mui/material/Modal";
import SigninForm from "./signin-form";
import SignupForm from "./signup-form";
import { PiUserCircle } from "react-icons/pi";
export interface InputProps {
inputs: {
name: string;
city: string;
email: string;
phone: string;
password: string;
};
handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
handleClose: () => void;
}
export default function LoginModal() {
const [isSignin, setIsSignin] = useState(false);
const [open, setOpen] = useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => {
console.log("handle close called");
setOpen(false);
};
useEffect(() => {
console.log("Modal state:", open);
}, [open]);
const [inputs, setInputs] = useState({
name: "",
city: "",
email: "",
phone: "",
password: "",
});
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputs({
...inputs,
[e.target.name]: e.target.value,
});
};
const props = {
inputs,
handleChange,
handleClose,
};
return (
<div>
<PiUserCircle size={30} className="text-primary" onClick={handleOpen} />
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style}>
{isSignin ? (
<>
<SigninForm props={props} />
<p className="text-center">
do not have an account?{" "}
<button
className="bg-secondary outline-0 border-0 underline"
onClick={() => setIsSignin(false)}
>
make one!
</button>
</p>
</>
) : (
<>
<SignupForm props={props} />
<p className="text-center">
have an account?{" "}
<button
className="bg-secondary outline-0 border-0 underline"
onClick={() => setIsSignin(true)}
>
sign in!
</button>
</p>
</>
)}
</Box>
</Modal>
</div>
);
}
我做了这部分,所以我知道模式是自行关闭还是通过我的钩子关闭,并且没有记录任何内容,但错误,错误:
const handleClose = () => {
console.log("handle close called");
setOpen(false);
};
useEffect(() => {
console.log("Modal state:", open);
}, [open]);
这是注册表单组件,包装器只是一个带有样式的div;防止默认在表单
onsubmit
和按钮 onclick
: 中都不起作用
import LoginWrapper from "./login-wrapper";
import { InputProps } from "./login-modal";
import { useContext, useEffect, useState } from "react";
import useAuth from "../../../hooks/useAuth";
import { AuthorizationContext } from "../../context/AuthContext";
import spinner from "../../icons/spinner.png";
import Image from "next/image";
export default function SignupForm({ props }: { props: InputProps }) {
const { inputs, handleChange, handleClose } = props;
const [disabled, setDisabled] = useState(true);
const { signup } = useAuth();
const { data, error, loading, setAuthState } =
useContext(AuthorizationContext);
useEffect(() => {
if (
inputs.name &&
inputs.city &&
inputs.email &&
inputs.password &&
inputs.phone
) {
setDisabled(false);
} else {
setDisabled(true);
}
}, [inputs]);
return (
<LoginWrapper>
{loading ? (
<Image src={spinner} alt="loading" />
) : (
<>
<div>welcome</div>
<div>register</div>
<form
onSubmit={(e) => {
e.preventDefault();
}}
className="flex flex-col gap-4 *:w-60 *:rounded-md *:p-2"
>
<input
type="text"
name="name"
id="name"
placeholder="name"
value={inputs.name}
onChange={(e) => handleChange(e)}
/>
<input
type="text"
name="city"
id="city"
placeholder="city"
value={inputs.city}
onChange={(e) => handleChange(e)}
/>
<input
type="text"
name="phone"
id="phone"
placeholder="phone"
value={inputs.phone}
onChange={(e) => handleChange(e)}
/>
<input
type="email"
name="email"
id="email"
placeholder="email"
value={inputs.email}
onChange={(e) => handleChange(e)}
/>
<input
type="password"
name="password"
id="password"
placeholder="password"
value={inputs.password}
onChange={(e) => handleChange(e)}
/>
<button
disabled={disabled}
onClick={(e) => {
e.preventDefault();
signup(inputs, handleClose);
}}
className="bg-primary text-white disabled:bg-secondary disabled:border disabled:border-primary disabled:text-primary"
>
Sign Up
</button>
</form>
<h1>{error ? error : ""}</h1>
</>
)}
</LoginWrapper>
);
}
这是用于进行 API 调用的自定义钩子:
import axios from "axios";
import { useContext } from "react";
import { AuthorizationContext } from "../app/context/AuthContext";
import { deleteCookie } from "cookies-next";
export default const useAuth = () => {
const { setAuthState } = useContext(AuthorizationContext);
const signin = async (
{ email, password }: { email: string; password: string },
handleClose: () => void
) => {
setAuthState({
data: null,
error: null,
loading: true,
});
try {
const response = await axios.post(`/api/auth/signin`, {
email,
password,
});
setAuthState({
data: response.data,
error: null,
loading: false,
});
if (response.status === 200 && response.data) {
handleClose();
}
} catch (error: any) {
console.log(error);
setAuthState({
data: null,
error: error.response.data.errorMessage,
loading: false,
});
}
};
const signup = async (
{
email,
password,
name,
phone,
city,
}: {
email: string;
password: string;
name: string;
phone: string;
city: string;
},
handleClose: () => void
) => {
setAuthState({
data: null,
error: null,
loading: true,
});
try {
const response = await axios.post(`/api/auth/signup`, {
email,
password,
name,
phone,
city,
});
setAuthState({
data: response.data,
error: null,
loading: false,
});
if (response.status === 200 && response.data) {
handleClose();
}
} catch (error: any) {
console.log(error);
setAuthState({
data: null,
error: error.response.data.errorMessage,
loading: false,
});
}
};
const signout = () => {
deleteCookie("jwt");
setAuthState({
data: null,
error: null,
loading: false,
});
};
return {
signin,
signup,
signout,
};
};
我希望它只有在注册成功后才关闭。
请问您有什么类型的数据?如果是数组,最好这样检查。
if (response.status === 200 && response.data && response.data.length > 0) { 处理关闭(); }