You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在基于useQuery的自定义React Hook中添加参数合法性校验?

解决React自定义Hook参数校验问题

首先纠正一个常见误区:React Hook的规则是禁止在条件语句、循环、嵌套函数中调用Hook,而非Hook内部不能写条件判断。你的原代码其实没有违反Hook规则,但参数校验的方式可以更合理,下面提供几种优化方案:


方案1:提前参数校验,直接返回错误状态

在Hook最开始就完成参数校验,不符合要求时直接返回预设的错误状态,避免后续不必要的请求逻辑执行:

import { useQuery } from "@tanstack/react-query";

export const useLiquidityPositions = (userAddress: string): GraphQLResponse<LiquidityPositions> => {
    // 提前校验地址合法性,不符合直接返回错误状态
    if (!isAddress(userAddress)) {
        return {
            status: 'error',
            loading: false,
            error: new Error('无效的用户地址格式'),
            response: undefined,
            payload: undefined
        };
    }

    const {
        status,
        isLoading: loading,
        error,
        data: response,
    } = useQuery({
        queryKey: ["USER_POSITIONS", userAddress],
        queryFn: async () => {
            const res = await getLiquidityPositionsData(userAddress);
            return res;
        }
    });

    const payload = response?.data;

    return { status, loading, error, response, payload }
}

方案2:用React Query的enabled控制请求触发

如果希望参数非法时Hook处于闲置状态,参数合法后自动触发请求,可以利用enabled配置项:

import { useQuery } from "@tanstack/react-query";

export const useLiquidityPositions = (userAddress: string): GraphQLResponse<LiquidityPositions> => {
    const isAddressValid = isAddress(userAddress);

    const {
        status,
        isLoading: loading,
        error,
        data: response,
    } = useQuery({
        queryKey: ["USER_POSITIONS", userAddress],
        queryFn: async () => {
            const res = await getLiquidityPositionsData(userAddress);
            return res;
        },
        // 仅当地址合法时才发起请求
        enabled: isAddressValid,
        // 可选:非法状态下的初始数据
        initialData: isAddressValid ? undefined : { data: undefined }
    });

    const payload = response?.data;

    // 单独处理非法参数的状态返回
    if (!isAddressValid) {
        return {
            status: 'idle',
            loading: false,
            error: new Error('无效的用户地址格式'),
            response: undefined,
            payload: undefined
        };
    }

    return { status, loading, error, response, payload }
}

方案3:在queryFn内抛出错误替代返回undefined

原代码返回undefined会导致调用方难以区分「参数错误」和「请求无数据」,改成抛出错误更清晰:

import { useQuery } from "@tanstack/react-query";

export const useLiquidityPositions = (userAddress: string): GraphQLResponse<LiquidityPositions> => {
    const {
        status,
        isLoading: loading,
        error,
        data: response,
    } = useQuery({
        queryKey: ["USER_POSITIONS", userAddress],
        queryFn: async () => {
            if (!isAddress(userAddress)) {
                throw new Error('无效的用户地址格式');
            }
            const res = await getLiquidityPositionsData(userAddress);
            return res;
        }
    });

    const payload = response?.data;

    return { status, loading, error, response, payload }
}

关键说明

  • 所有方案都没有违反React Hook规则,因为我们没有在条件语句中调用useQuery这类Hook,只是在Hook内部做逻辑判断。
  • 提前校验能减少无效的资源消耗,enabled方案更适合参数动态变化的场景,抛出错误则能让调用方通过error字段明确感知问题类型。

内容的提问来源于stack exchange,提问作者code_learner93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:35:20