React Query依赖Mutation问题:注册后无法重新触发登录函数
问题分析与解决方案
你的代码里递归调用handleLogin失效,核心原因是函数依赖项不全和回调时机选择不当,具体修复如下:
关键问题点
- useCallback依赖缺失:
handleLogin内部用到了internalQueryClient、getInstallationId等多个外部变量,但依赖数组只声明了login和register,导致React无法更新函数引用,递归时调用的是旧版本的handleLogin。 - useEffect依赖缺失:初始化的
useEffect没有把handleLogin加入依赖,组件启动时调用的是初始版本的函数,后续更新无法同步。 - 注册回调时机错误:用
onSettled会在注册成功/失败时都触发登录,应该只在注册成功后执行。
修复后的代码
const { mutate: login } = useLogin() const { mutate: register } = useRegister() const internalQueryClient = useQueryClient() const handleLogin = useCallback(async () => { const installationID = await getInstallationId() login( { deviceId: installationID }, { onSuccess: (loginResult) => { saveAccessToken(loginResult) }, onError: (error) => { if (error.response?.status === HttpStatus.NOT_FOUND) { register( { deviceInfos: { deviceId: installationID, platform: Platform.OS.toUpperCase(), appBuildNumber: getBuildNumber(), }, subscription: { packageSubscribe: 'NONE', lastPaymentDate: null, paymentDeadline: null, }, }, { // 仅注册成功后触发重新登录 onSuccess: async () => { await internalQueryClient.invalidateQueries({ queryKey: [QueryUrl.auth.login], }) handleLogin() }, }, ) } }, }, ) }, [login, register, internalQueryClient, getInstallationId, saveAccessToken, HttpStatus, Platform, getBuildNumber, QueryUrl.auth.login]) useEffect(() => { const init = async () => { await handleLogin() } init() }, [handleLogin])
修复说明
- 补全useCallback依赖:将所有
handleLogin内部用到的外部变量/函数都加入依赖数组,确保React能跟踪函数更新,递归调用的是最新版本。 - 替换为onSuccess回调:只在注册成功后执行登录逻辑,避免无效递归。
- 修正useEffect依赖:把
handleLogin加入依赖数组,保证初始化时调用的是最新的函数引用。
内容的提问来源于stack exchange,提问作者Brice Zele
相关产品推荐
相关产品推荐

