React 19引入use hook后,如何在状态变化或点击时触发重新请求?
React 19 use Hook 触发重新请求的实现方式
React 19 引入的 use Hook 可以替代带状态更新的 useEffect 完成数据请求,但遇到需要在状态变化、按钮点击时重新获取数据的场景,我们可以利用 use Hook 的依赖特性来实现,无需强制组件重渲染或手动维护状态。
旧的 useEffect 实现方式(对比参考)
之前我们通常会用一个触发状态配合 useEffect 来实现重新请求:
const [joke, setJoke] = useState([]); const [loading, setLoading] = useState(true); const [shouldRefetch, setShouldRefetch] = useState(false) useEffect(() => { const fetchJoke = async () => { try { const res = await fetch('https://api.chucknorris.io/jokes/random'); const data = await res.json(); setJoke(data); setLoading(false); } catch (error) { console.error(error); } finally { setLoading(false); } }; fetchJoke(); }, [shouldRefetch]);
React 19 use Hook 基础写法
const JokeItem = () => { const joke = use(apiCall()); return ( <div className="bg-blue-50 shadow-md p-4 my-6 rounded-lg"> <h2 className="text-xl font-bold">{joke.value}</h2> </div> ); };
触发重新请求的几种实用方法
方法1:用触发状态作为依赖
use Hook 会监听传入的异步函数的依赖数组,当依赖变化时,会重新执行异步操作。我们可以定义一个触发状态,通过更新它来触发重新请求:
import { use, useState } from 'react'; // 封装请求逻辑 const fetchJoke = async () => { const res = await fetch('https://api.chucknorris.io/jokes/random'); return res.json(); }; const JokeItem = () => { // 用一个计数器作为触发标志 const [refetchKey, setRefetchKey] = useState(0); // 依赖refetchKey,每次更新都会重新执行fetchJoke const joke = use(() => fetchJoke(), [refetchKey]); return ( <div className="bg-blue-50 shadow-md p-4 my-6 rounded-lg"> <h2 className="text-xl font-bold">{joke.value}</h2> <button onClick={() => setRefetchKey(prev => prev + 1)} className="mt-4 px-4 py-2 bg-blue-600 text-white rounded" > 获取新笑话 </button> </div> ); };
方法2:封装自定义 Hook 实现可手动触发的请求
把请求和重新触发逻辑封装成自定义 Hook,让组件调用更简洁:
import { use, useState, useCallback } from 'react'; const useJoke = () => { const [refetchKey, setRefetchKey] = useState(0); const joke = use(() => { return fetch('https://api.chucknorris.io/jokes/random').then(res => res.json()); }, [refetchKey]); // 封装重新请求方法 const refetch = useCallback(() => { setRefetchKey(prev => prev + 1); }, []); return { joke, refetch }; }; const JokeItem = () => { const { joke, refetch } = useJoke(); return ( <div className="bg-blue-50 shadow-md p-4 my-6 rounded-lg"> <h2 className="text-xl font-bold">{joke.value}</h2> <button onClick={refetch} className="mt-4 px-4 py-2 bg-blue-600 text-white rounded" > 获取新笑话 </button> </div> ); };
方法3:直接传入新的 Promise 实例
use Hook 会在传入的 Promise 实例变化时重新执行请求,因此可以每次触发时创建新的请求 Promise:
import { use, useState } from 'react'; const fetchJoke = async () => { const res = await fetch('https://api.chucknorris.io/jokes/random'); return res.json(); }; const JokeItem = () => { const [requestPromise, setRequestPromise] = useState(() => fetchJoke()); const joke = use(requestPromise); return ( <div className="bg-blue-50 shadow-md p-4 my-6 rounded-lg"> <h2 className="text-xl font-bold">{joke.value}</h2> <button onClick={() => setRequestPromise(fetchJoke())} className="mt-4 px-4 py-2 bg-blue-600 text-white rounded" > 获取新笑话 </button> </div> ); };
以上几种方法都不需要额外维护请求结果的状态,完全利用 React 19 use Hook 的特性实现重新请求,代码更简洁且符合 React 新特性的设计思路。
内容的提问来源于stack exchange,提问作者Janjac
相关产品推荐
相关产品推荐

