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

React异步自定义Hook调用问题:如何等待一个Hook结果再用另一个?

解决方案:正确处理自定义Hook中的异步逻辑

你的核心问题在于第一个自定义Hook直接返回了Promise,而React组件渲染是同步的,无法直接等待Promise完成后再执行后续逻辑。正确的做法是在Hook内部用状态管理异步结果,配合React Query的enabled选项控制查询时机。

步骤1:重构第一个自定义Hook

把异步请求的结果存在state里,同时暴露加载状态,让调用方知道什么时候数据准备好:

import { useState, useEffect } from 'react';

export const useMetamask = () => { // 注意Hook命名规范:小写开头+use前缀
    const [wallet, setWallet] = useState<string | null>(null);
    const [isLoading, setIsLoading] = useState(true);
    const [error, setError] = useState<Error | null>(null);

    useEffect(() => {
        const fetchWallet = async () => {
            try {
                // 先检查Metamask是否存在
                if (!window.ethereum) {
                    throw new Error('Metamask未安装');
                }
                const accounts: string[] = await window.ethereum.request({
                    method: 'eth_requestAccounts'
                });
                setWallet(accounts[0]);
            } catch (e) {
                const err = e as Error;
                console.error(err);
                setError(err);
                setWallet(null);
            } finally {
                setIsLoading(false);
            }
        };

        fetchWallet();
    }, []);

    return { wallet, isLoading, error };
};

步骤2:在React Query中依赖异步结果

使用重构后的Hook,通过enabled选项让React Query只在wallet有值时才发起请求:

import { useQuery } from '@tanstack/react-query';
import { useMetamask } from './useMetamask';

// 第二个自定义Hook或组件中使用
export const useUserByWallet = () => {
    const { wallet, isLoading: isWalletLoading, error: walletError } = useMetamask();

    const { data: user, isLoading: isUserLoading, error: userError } = useQuery({
        queryKey: ['user', wallet],
        queryFn: () => getUserByWallet(wallet!), // wallet有值时才执行,所以用!断言
        enabled: !!wallet, // 只有wallet不为null/undefined时才触发查询
        retry: false // 可选:如果wallet获取失败,不需要重试查询
    });

    return {
        user,
        isLoading: isWalletLoading || isUserLoading,
        error: walletError || userError
    };
};

关键说明

  • Hook命名规范:React官方要求Hook必须以use开头且小写字母起始,所以把UseMetamask改成useMetamask。
  • 状态管理异步结果:用useState存储wallet、加载状态和错误,useEffect触发异步请求,确保组件渲染时能同步获取当前状态。
  • React Query的enabled选项:这是控制依赖异步数据查询的核心,只有当依赖的wallet存在时,才执行getUserByWallet请求,避免传入Promise或无效值。

内容的提问来源于stack exchange,提问作者Wesley van S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 13:10:48