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

如何实现自定义Hook获取Snapshot提案数据并正确返回数据?

问题解决:自定义Hook返回Pending Promise的处理方案

你当前的核心问题是:自定义Hook直接返回了request方法的Promise实例,而React组件无法直接处理这种异步返回值,所以打印出来是Promise{<pending>}。要实现符合React Hooks规范的异步数据获取,必须结合useState和useEffect来管理异步状态。

修改后的完整代码

import { useState, useEffect } from 'react';
import { gql, request } from 'graphql-request';

export const useSnapshotProposals = gql`
  query Proposals {
    proposals(
      first: 20
      skip: 0
      where: { space_in: ["example.eth"] }
      orderBy: "created"
      orderDirection: desc
    ) {
      id
      title
      body
      choices
      start
      end
      snapshot
      state
      author
      space {
        id
        name
      }
    }
  }
`;

export const useSnapshotProposalsQuery = () => {
  // 初始化状态:存数据、加载状态、错误信息
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    // 封装异步请求函数
    const fetchProposals = async () => {
      try {
        const result = await request('https://hub.snapshot.org/graphql', useSnapshotProposals);
        setData(result);
      } catch (err) {
        setError(err);
      } finally {
        setLoading(false);
      }
    };

    fetchProposals();
  }, []); // 空依赖数组确保请求只在组件挂载时执行一次

  return { data, loading, error };
};

组件中使用方式

现在你可以按照预期的方式调用Hook,并处理加载、错误和数据状态:

function ProposalsList() {
  const { data, loading, error } = useSnapshotProposalsQuery();

  if (loading) return <div>加载提案中...</div>;
  if (error) return <div>请求失败:{error.message}</div>;

  return (
    <div className="proposals-container">
      {data?.proposals.map(proposal => (
        <div key={proposal.id} className="proposal-card">
          <h3>{proposal.title}</h3>
          <p>发起者:{proposal.author}</p>
          <p>状态:{proposal.state}</p>
        </div>
      ))}
    </div>
  );
}

关键修改说明

  1. 状态管理:用useState创建三个状态变量,分别存储请求结果、加载状态和错误信息,让组件能感知异步请求的不同阶段。
  2. 异步执行时机:用useEffect包裹请求逻辑,确保请求在组件挂载后执行,且仅执行一次(通过空依赖数组)。
  3. Promise处理:用async/await语法简化异步代码的可读性,同时通过try/catch/finally处理成功、失败和请求完成的状态更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:25:17