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

如何在TypeScript中点击按钮调用自定义React Hook拉取API数据并展示在Div中

问题根源

  1. 自定义useFetch Hook 内的useEffect依赖项只有url和setState,你传入的url固定为/api/rand没有变化,所以只会在Hook首次挂载时发起一次请求,后续不会自动重发。
  2. App组件内点击按钮只是把已经请求到的data赋值给本地的quote状态,完全没有触发新的请求逻辑,自然拿不到新数据。

修复方案

第一步:修改useFetch,新增手动刷新能力

我们给useFetch封装独立的请求方法,同时返回手动触发请求的refetch函数:

import { useEffect, useState, useCallback } from "react";

export interface Payload {
  data: null | string,
  loading: boolean
}

const useFetch = (url: string) => {
  const [state, setState] = useState<Payload>({data: null, loading: true});
  // 用useCallback缓存请求逻辑,避免不必要的重建
  const fetchData = useCallback(() => {
    setState(prev => ({ data: prev.data, loading: true }));
    fetch(url)
      .then(x => x.text())
      .then(y => {
        setState({ data: y, loading: false });
      });
  }, [url]);

  // 首次挂载自动请求一次,如果需要点击才首次加载可以删掉这个useEffect
  useEffect(() => {
    fetchData();
  }, [fetchData]);

  // 返回状态和刷新函数
  return {
    ...state,
    refetch: fetchData
  };
}

export default useFetch;

第二步:修改App组件逻辑,删除冗余状态

原来单独存储的quote状态完全没必要,直接复用useFetch返回的数据即可,点击按钮直接调用refetch触发新请求:

import React from "react";
import useFetch from './utils/useFetch';

const App = () => {
  // 从useFetch拿到请求状态和刷新方法
  const { data, loading, refetch } = useFetch("/api/rand");

  return (
    <div>
      <h1>Quotes</h1>
      <button onClick={refetch} disabled={loading}>
        {loading ? "加载中..." : "Get Quote"}
      </button>
      <div>{data}</div>
    </div>
  )
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:54:03