注册模态重新渲染并关闭在提交下一个js上进行的API调用

问题描述 投票:0回答:1

我有一个模态组件,可以有条件地呈现登录和注册表单,当我单击任何表单上的提交按钮时,即使调用不成功,模态也会关闭。 我在这个存储库中部署了我的代码。

这是我的模态:

"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,
  };
};

我希望它只有在注册成功后才关闭。

javascript reactjs next.js material-ui next-auth
1个回答
0
投票

请问您有什么类型的数据?如果是数组,最好这样检查。

if (response.status === 200 && response.data && response.data.length > 0) { 处理关闭(); }

© www.soinside.com 2019 - 2024. All rights reserved.