blitz icon indicating copy to clipboard operation
blitz copied to clipboard

useQuery refetchInterval option is invalid

Open StringKe opened this issue 2 years ago • 1 comments

What is the problem?

Maybe the useQuery refetchInterval option is invalid

My code logic is like this:

  1. The page loads and requests a QR code valid for 5 minutes and waits for the user to scan the code
  2. When the QR code request is successful, it will start polling every second to request the backend to check whether the user scans the code.

Paste all your error logs here:

No relevant code, only browser console request logging

video: https://share.cleanshot.com/88PtdG

In the fifth second of the video, I completed the operation of scanning the code on my mobile phone.

Paste all relevant code snippets here:

import { useQuery } from "@blitzjs/rpc"
import React from "react"
import getWechatMpQrState from "../app/auth/queries/getWechatMpQrState"
import getWechatMpQr from "../app/auth/queries/getWechatMpQr"

function WechatQr() {
  const [cacheId, setCacheId] = React.useState<string | undefined>()
  const [canLoopState, setCanLoopState] = React.useState<boolean>(false)

  const [state, stateAction] = useQuery(
    getWechatMpQrState,
    { id: cacheId },
    {
      refetchInterval: 1000,
      refetchOnMount: false,
      suspense: false,
      useErrorBoundary: false,
      enabled: canLoopState,
      retry: false,
      onSuccess: (data) => {
        if (data) {
          console.log(data)
        }
      },
      onError: (_) => {
      }
    }
  )

  const [wechatQr, wechatQrAction] = useQuery(
    getWechatMpQr,
    { id: cacheId },
    {
      refetchInterval: 1000 * 60 * 5,
      onSuccess: (data) => {
        setCacheId(data.dataId)
        setCanLoopState(true)
      }
    }
  )

  React.useEffect(() => {
    console.log(cacheId)
  }, [cacheId])

  return (
    <div>{wechatQr && <img alt={"qrcode"} className={"max-w-xs"} src={wechatQr.qrUrl} />}</div>
  )
}

function AuthPage() {
  return <div>
    <div>qr</div>
    <React.Suspense>
      <WechatQr />
    </React.Suspense>
  </div>
}

export default AuthPage

getWechatMpQr.ts

import { isEmpty, isString } from 'lodash'
import { nanoid } from 'nanoid'
import { z } from 'zod'

import { Ctx } from 'blitz'

import { wechatHelper } from 'integrations/wechat/WechatHepler'

export const GetWechatQr = z.object({
    id: z.string().optional(),
})

export async function getWechatQrDataId(input: { id?: string }, ctx: Ctx) {
    const data = GetWechatQr.parse(input)
    let dataId: string | undefined = data.id

    if (isEmpty(dataId)) {
        const saveId = ctx.session.$publicData.wechatId!
        if (saveId && isString(saveId)) {
            dataId = saveId
        }
    }

    if (isEmpty(dataId)) {
        dataId = nanoid(12)
        await ctx.session.$setPublicData({
            wechatId: dataId,
        })
    }
    return dataId as string
}

export default async function getWechatMpQr(input: z.infer<typeof GetWechatQr>, ctx: Ctx) {
    const dataId = await getWechatQrDataId(input, ctx)

    return {
        dataId,
        ...(await wechatHelper.createLoginQr(dataId)),
    }
}

getWechatMpQrState.tx

import { z } from "zod"

import { Ctx } from "blitz"

import db, { User } from "../../../db"

import { WechatHelper } from "integrations/wechat/WechatHepler"

import commonRedis from "integrations/CommonRedis"
import { GetWechatQr, getWechatQrDataId } from "./getWechatMpQr"
import { transformUserSession } from "../utils"

export default async function getWechatMpQrState(input: z.infer<typeof GetWechatQr>, ctx: Ctx): Promise<User | null> {
  const dataId = await getWechatQrDataId(input, ctx)

  const successId = `${WechatHelper.LOGIN_EVENT_SUCCESS}${dataId}`

  if (await commonRedis.exists(successId)) {
    const userId = await commonRedis.get(successId)
    if (userId) {
      const user = await (db.user.findFirst({
        where: { id: Number(userId) }
      }))
      if (user) {
        await ctx.session.$create(transformUserSession(user))
        return user
      }
    }
  }
  return null
}

What are detailed steps to reproduce this?

I didn't reproduce the problem, I can upload the code to the private repo and invite (reply me under issuse)

Run blitz -v and paste the output here:

➜ blitz -v
Loaded env from /Users/chen/Project/Company/Yinbaitu/36pic/.env.local
Loaded env from /Users/chen/Project/Company/Yinbaitu/36pic/.env
Blitz version: 2.0.0-alpha.57 (global)
Blitz version: 2.0.0-alpha.57 (local)
macOS Monterey | darwin-arm64 | Node: v18.4.0


 Package manager: npm

  System:
    OS: macOS 12.4
    CPU: (10) arm64 Apple M1 Max
    Memory: 400.39 MB / 64.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.4.0 - ~/.nvm/versions/node/v18.4.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.4.0/bin/yarn
    npm: 8.12.1 - ~/.nvm/versions/node/v18.4.0/bin/npm
  npmPackages:
    @blitzjs/auth: 2.0.0-alpha.57 => 2.0.0-alpha.57
    @blitzjs/next: 2.0.0-alpha.57 => 2.0.0-alpha.57
    @blitzjs/rpc: 2.0.0-alpha.57 => 2.0.0-alpha.57
    @prisma/client: 4.1.0 => 4.1.0
    blitz: 2.0.0-alpha.57 => 2.0.0-alpha.57
    next: 12.2.0 => 12.2.0
    prisma: 4.1.0 => 4.1.0
    react: 18.0.0 => 18.0.0
    react-dom: 18.0.0 => 18.0.0
    typescript: ^4.5.3 => 4.7.4


Please include below any other applicable logs and screenshots that show your problem:

import React from "react"
import getWechatMpQrState from "../app/auth/queries/getWechatMpQrState"
import getWechatMpQr from "../app/auth/queries/getWechatMpQr"
import { useQuery } from "@tanstack/react-query"

function WechatQr() {
  const [cacheId, setCacheId] = React.useState<string | undefined>(undefined)
  const [canLoopState, setCanLoopState] = React.useState<boolean>(false)

  const { data: state, ...stateAction } = useQuery(["wechat-qr-state", cacheId],
    () => {
      return getWechatMpQrState({ id: cacheId }, undefined as never)
    },
    {
      refetchInterval: 1000,
      refetchOnMount: false,
      suspense: false,
      useErrorBoundary: false,
      enabled: canLoopState,
      retry: false,
      onSuccess: (data) => {
        if (data) {
          console.log(data)
        }
      },
      onError: (_) => {
      }
    }
  )

  const { data: wechatQr, ...wechatQrAction } = useQuery(["wechat-qr", cacheId],
    () => {
      return getWechatMpQr({ id: cacheId }, undefined as never)
    },
    {
      refetchInterval: 1000 * 60 * 5,
      refetchOnMount: "always",
      refetchOnWindowFocus: "always",
      refetchOnReconnect: "always",
      enabled: true,
      onSuccess: (data) => {
        // setCacheId(data.dataId)
        setCanLoopState(true)
      }
    }
  )

  React.useEffect(() => {
    setCacheId(Math.random().toString())
  }, [])

  return (
    <div>{wechatQr && <img alt={"qrcode"} className={"max-w-xs"} src={wechatQr.qrUrl} />}</div>
  )
}

function AuthPage2() {
  return <div>
    <div>qr</div>
    <React.Suspense>
      <WechatQr />
    </React.Suspense>
  </div>
}

export default AuthPage2

I try to use @tanstack/react-query directly and it doesn't work

StringKe avatar Jul 25 '22 06:07 StringKe

Thanks for the report! We'll try to investigate soon

beerose avatar Jul 25 '22 09:07 beerose