在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
相关产品推荐
相关产品推荐

