NextJS App Router 以react-hook-form 重定向

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

我正在尝试做类似于这个问题的事情。我有一个登录页面,表单检查提交的电子邮件是否有帐户;如果没有,我希望它重定向到注册页面:

const onSubmit = async (data) => {
  const { email } = data;

  const res = await checkUser(email)
  .then(async (isUser) => {
    if (isUser) {
      // do proper authentication
    } else {
      redirect('/register'); 
    }
  })
}

对上一个问题的唯一赞成的答案说:“据我所知,

redirect
方法只能在服务器上使用”,然后继续建议使用
useRouter
。现在,我可以做到这一点,但这是一个基于 NextJS 13 App-Router 的应用程序,与该答案中的建议相反,文档说,“
redirect
可以在服务器组件、客户端组件、路由中使用处理程序和服务器操作。”所以,我觉得我应该使用
redirect

不幸的是,它

throw
被调用的时候。现在,这种行为也被记录下来,并且是它应该做的。但是,它并没有真正重定向,而是被困在我的
catch
块中。

问题的有效(即无效)示例可以在 CodeSandbox 中找到。

虽然比问题的 CodeSandbox 演示更详细,但我的实际代码如下所示,评论中提到了三种不同的尝试(a、b 和 c):

const onSubmit = async (data, toast) => {

  const { email } = data;

  const res = await checkUser(email)
  .then(async (isUser) => {
    if (isUser) {
      const cb = await signIn('email', {
        email: email,
        callbackUrl: '/profile'
      });

      return cb;
    } else {
      redirect('/register'); // option a & b passes through to catch block below
      // throw new Error('NFU'); // option (c)
    }
  })
  .then((callback) => {
    if (callback?.error) {
      throw new Error(callback.error);
    } else if (callback?.ok) {
      toast.create({
        title: 'Congratulations!',
        description: `You're signed in!`,
        status: 'success',
        duration: 5000
      });

      // return true; // part of c, below
    }
  })
  .catch(((error) => {
    // option b, re-throw if we got a 404 from the checkUser call; 
    // unhandled runtime error
    if(isRedirectError(error)) throw error;
    // 
    // if ('NFU' === error.message) return false; // part of (c), below
    toast.create({
      title: 'Error',
      description: error.message,
      status: 'error',
      duration: 5000
    });
  }))

  // if (!res) redirect('/register') // option c, unhandled runtime error
}

在选项(a)中,我只是调用

redirect
,我认为这会起作用,但它却被困在
catch
中。选项 (b) 来自 5 月份 Vercel GitHub 上的此讨论,有关在服务器操作中使用
redirect
。那是在 App Router 离开实验状态之前,我所做的不是服务器操作;而是在 App Router 离开实验状态之前。尽管如此,我想我应该尝试一下:如果是
throw
,只需从
catch
内部重新重新
isRedirectError
错误即可。但这会导致客户端出现未处理的运行时错误,而不是重定向。

最后(选项c),我尝试从承诺链中完全删除

redirect
,将
res
设置为
true
false
,然后调用
redirect
(如果为假);但这也会导致未处理的运行时错误。

我该如何进行这项工作?

为了完整起见,可能值得注意的是,这个

onSubmit
函数实际上传递给
handleSubmit
,因为表单是由 RHF 管理的。

此外,

onSubmit
函数是在组件外部定义的,因为整个事物都包装在
FormProvider
上下文中,其中
form
submit
按钮是共享
onSubmit
代码的不同组件。

next.js try-catch next.js13 react-hook-form
1个回答
0
投票

我在这里使用服务器操作发布了一个解决方案。 https://github.com/vercel/next.js/discussions/57495#discussioncomment-8633077

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