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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 23:47:47