有什么方法可以在 formik onSubmit 之前 运行 一个 onClick 事件吗?

Is there any way to run an onClick event before a formik onSubmit?

我正在尝试使用以下提交按钮创建登录页面

<Button
  color="primary"
  disabled={isSubmitting}
  fullWidth
  size="large"
  type="submit"
  variant="contained"
  onClick={() => { login(values.email, values.password); }}>
  Sign in
</Button>

登录逻辑如下所示

const login = async (email, password) => {
  try {
    const user = await signInWithEmailAndPassword(
      auth,
      email,
      password
    );
    console.log('User: ', user);
    authenticated = true;
    console.log('Authenticated: ', authenticated);
  } catch (error) {
    console.log('Error: ', error);
    authenticated = false;
  }
};

我的 formik 组件看起来像这样

<Formik
  initialValues={{
    email: '',
    password: ''
  }}
  validationSchema={Yup.object().shape({
    email: Yup.string().email('Must be a valid email').max(255).required('Email is required'),
    password: Yup.string().max(255).required('Password is required')
  })}
  onSubmit={() => {
    console.log('Authenticated: ', authenticated);
    if (authenticated === true) {
      navigate('/app/dashboard', { replace: true });
    }
  }}
>

我的想法是获取提交按钮的onClick,到运行 onSubmit 运行s 之前的登录逻辑,这会将authenticated 设置为true并允许用户重定向到 Dashboard.js。目前,似乎 onSubmit 运行s 在 onClick 之前,导致 authenticated 的默认值为 false,因此不会将用户重定向到仪表板。

由于您的登录函数是一个异步函数,它return是一个承诺,因此 onSubmit 中的登录是异步运行的。

可以在onSubmit里面调用login函数,但是需要等待promsie完成

例如:

<Formik
  initialValues={{
    email: '',
    password: ''
  }}
  validationSchema={Yup.object().shape({
    email: Yup.string().email('Must be a valid email').max(255).required('Email is required'),
    password: Yup.string().max(255).required('Password is required')
  })}
  onSubmit={() => {
    login(email, password)
    .then(() => {
      console.log('Authenticated: ', authenticated);
      if (authenticated === true) {
        navigate('/app/dashboard', { replace: true });
      }
    })
    .catch((error) => {
       // handle error
    })
  }}
>

此外,您可以简单地从登录函数 return 并在承诺成功处理程序中使用它,而不是在范围外设置变量 authenticated

const login = async (email, password) => {
  try {
    const user = await signInWithEmailAndPassword(
      auth,
      email,
      password
    );
    console.log('User: ', user);
    return true
  } catch (error) {
    console.log('Error: ', error);
    throw error
  }
};
  onSubmit={() => {
    login(email, password)
    .then((isAuthenticated) => {
      console.log('Authenticated: ', isAuthenticated);
      if (isAuthenticated === true) {
        navigate('/app/dashboard', { replace: true });
      }
    })
    .catch((error) => {
       // handle error
    })
  }}

请阅读并了解更多关于 javascript 承诺、异步 javascript 及其工作原理的信息。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise