为什么 React 在 router.push("/") 之前渲染表单一秒钟

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

这是我的登录页面(我使用 Next.js 14)。

当 setSubmitting true - 在页面上加载微调器渲染时,但由于某种原因,在页面实际路由到/主页之前 isSubmitting 变为 false,并且表单在路由之前再次显示一秒钟。

"use client";
import UnderlinedInput from "@/components/underlined-input";
import { Button, cn } from "@nextui-org/react";
import { FormikHelpers, useFormik } from "formik";
import { useRouter } from "next/navigation";
import { object, string } from "yup";
import Link from "next/link";
import { useAppDispatch } from "@/hooks/store";
import { loginUser } from "@/store/auth/authSlice";
import LoadingSpinner from "@/components/loading-spinner";

interface InitialValues {
  email: string;
  password: string;
}

const validationSchema = object({
  email: string().email().required("email is required"),
  password: string().min(5).max(20).required("password is required"),
});

const Login = () => {
  const router = useRouter();
  const dispatch = useAppDispatch();

  const {
    errors,
    values,
    handleSubmit,
    handleChange,
    handleBlur,
    isSubmitting,
    touched,
  } = useFormik<InitialValues>({
    initialValues: {
      email: "",
      password: "",
    },
    validationSchema,
    onSubmit: onSubmit,
  });

  async function onSubmit(
    values: InitialValues,
    { setSubmitting, resetForm, setErrors }: FormikHelpers<InitialValues>
  ) {
    try {
      setSubmitting(true);
      await dispatch(loginUser(values)).unwrap();
      router.push("/");

    } catch (error) {
      console.log(error);
      setErrors({
        email: "invalid email or password",
        password: "invalid email or password",
      });
    } finally {
      setSubmitting(false);
    }
  }

  if (isSubmitting) {
    return <LoadingSpinner />;
  }

  return (
    <div>
        //form structure
    </div>
  );
};

export default Login;

ps: 我尝试使用带有超时的简单 Promise,而不是调度 async thunk,但问题不在于其中

reactjs typescript next.js react-redux formik
1个回答
0
投票

您需要在使用

await
的线路上按
router.push("/")
。原因是由于
router.push("/")
的异步特性。当执行
setSubmitting(false)
行时,
isSubmitting
变为 false,并且在导航完成之前再次显示表单。

async function onSubmit(
  values: InitialValues,
  { setSubmitting, resetForm, setErrors }: FormikHelpers<InitialValues>
) {
  try {
    setSubmitting(true);
    await dispatch(loginUser(values)).unwrap();
    await router.push("/"); // <--- await here
  } catch (error) {
    console.log(error);
    // ...rest of code
© www.soinside.com 2019 - 2024. All rights reserved.