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

在React中点击按钮时如何调用自定义useFetch hook获取数据?

React 手动触发useFetch请求的最佳实践

核心改造思路

你的核心问题是现有useFetch只支持组件挂载自动执行,没有开放手动触发的入口。通用解决方案是给useFetch增加手动触发模式,返回一个可调用的请求函数,完全符合Hook调用规则的同时满足按需触发请求的需求。

1. 改造useFetch的代码示例

import { useState, useEffect, useCallback } from 'react'

function useFetch(url, options = {}) {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState(null)
  // 新增autoFetch参数,默认true兼容原有自动请求场景
  const { autoFetch = true, ...fetchOptions } = options

  // 把请求逻辑封装成可复用的回调函数,支持传入覆盖参数
  const runFetch = useCallback(async (overrideOptions = {}) => {
    setLoading(true)
    setError(null)
    try {
      const res = await fetch(url, { ...fetchOptions, ...overrideOptions })
      const result = await res.json()
      setData(result)
      return result
    } catch (err) {
      setError(err)
      throw err
    } finally {
      setLoading(false)
    }
  }, [url, JSON.stringify(fetchOptions)])
  // 注:如果请求参数比较复杂,建议用深比较的依赖处理,或者传入options时先用useMemo包裹

  // 只有autoFetch为true时才在挂载时自动执行请求
  useEffect(() => {
    if (autoFetch) {
      runFetch()
    }
  }, [autoFetch, runFetch])

  return { data, loading, error, runFetch }
}

2. 加载更多场景的组件使用示例

function ItemList() {
  const [page, setPage] = useState(1)
  const [itemList, setItemList] = useState([])
  // 关闭自动请求,拿到手动触发函数
  const { loading, runFetch } = useFetch('/api/items', {
    autoFetch: false,
    method: 'GET'
  })

  const handleLoadMore = async () => {
    const nextPage = page + 1
    // 调用请求函数时传入动态分页参数
    const newItems = await runFetch({
      params: { page: nextPage, pageSize: 10 }
    })
    setItemList(prev => [...prev, ...newItems])
    setPage(nextPage)
  }

  return (
    <div>
      {/* 列表渲染逻辑 */}
      {itemList.map(item => <div key={item.id}>{item.content}</div>)}
      <button onClick={handleLoadMore} disabled={loading}>
        {loading ? '加载中' : '加载更多条目'}
      </button>
    </div>
  )
}

无需改造useFetch的替代方案

如果暂时不想修改现有useFetch的封装,也可以用状态驱动请求:给useFetch的依赖数组新增一个触发器参数,组件内声明const [fetchTrigger, setFetchTrigger] = useState(0),点击按钮时执行setFetchTrigger(prev => prev + 1),即可触发useFetch重新执行请求。这种方式适合简单场景,动态传参的灵活度低于返回runFetch的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 07:57:02