如何在TypeScript中点击按钮调用自定义React Hook拉取API数据并展示在Div中
问题根源
- 自定义
useFetchHook 内的useEffect依赖项只有url和setState,你传入的url固定为/api/rand没有变化,所以只会在Hook首次挂载时发起一次请求,后续不会自动重发。 - 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
相关产品推荐
相关产品推荐

