reactjs RTK查询变异在StrictMode下执行两次

2guxujil  于 2023-02-22  发布在  React
关注(0)|答案(1)|浏览(144)

我使用RTK查询进行数据提取,在其中一个用例中遇到了一个小问题。
我使用一个变体来验证应用程序用户的电子邮件地址,如下所示:

// ...imports

const ConfirmEmail = () => {
  const [params] = useSearchParams();

  const [confirmEmail, { isLoading, isSuccess, isUninitialized, error }] =
    useConfirmEmailMutation();

  useEffect(() => {
    if (isUninitialized) {
      confirmEmail({
        email: params.get('email'), // from the verification link
        code: params.get('code'), // from the verification link
      })
        .unwrap()
        .then(() => {
            // handling success...
        })
        .catch((e) => {
            // handling error...
        });
    }
  });

  // ...other component code
}

问题是StrictMode在开发过程中运行了两次变异,这导致了API端的并发错误。我在开发工具中看到两个网络请求,一个成功,另一个失败,根据哪个先运行,组件显示不一致的结果。
我知道这只会在开发过程中发生,我尝试按照官方react文档中的说明操作,并尝试使用此处所述的fixedCacheKey,但无法使用RTK Query进行操作,因此无法在开发过程中获得一致的结果
有办法吗,还是我错过了什么?

**编辑:**我的问题与this question福尔斯同一类别,但它更具体地针对RTK查询。因为在RTK查询中,如果一个组件试图进行与现有查询相同的查询,则不会执行任何请求(如此处所述)。然而,我试图做的是一个变异,以便确认用户的电子邮件地址(单击通过电子邮件发送的链接后)。变异不遵循此处所述的相同规则。

useEffect清理功能没有帮助,这不像购买产品示例。
根据以下讨论,可用的备选方案有:
1.使用查询而不是变异。但这在语义上是不正确的。
1.强迫用户再次点击一个按钮来启动“确认电子邮件”的变化。这是重复的,不方便用户。
1.使用一个ref来跟踪一个变异是否已经在运行,这是我在最后实现的,如下所示:

// ...imports

const ConfirmEmail = () => {
  const verifiying = useRef(false);

  const [params] = useSearchParams();

  const [confirmEmail, { isLoading, isSuccess, isUninitialized, error }] =
    useConfirmEmailMutation();

  useEffect(() => {
    const isVerifying = verifiying.current;

    if (isUninitialized) {
      verifiying.current = true;

      confirmEmail({
        email: params.get('email'), // from the verification link
        code: params.get('code'), // from the verification link
      })
        .unwrap()
        .then(() => {
            // handling success...
        })
        .catch((e) => {
            // handling error...
        });
    }
  });

  // ...other component code
}
vawmfj5a

vawmfj5a1#

不过,这正是严格性检查的重点:以显示您正在自动执行有问题的API调用。
将来,React可以选择在更多情况下执行一个带有空依赖项数组的useEffect,而不仅仅是在第一次挂载时--例如,与他们正在开发的屏幕外特性相结合。
这只是提前告诉你,你正在做这件事可能是在一个危险的地方。
你能不能把这个API调用合并到一些实际的用户交互中,比如点击按钮,这样会更安全。

相关问题