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

React中如何为4个数据端点实现无整页刷新的刷新按钮

实现方案

按以下步骤改造即可实现点击按钮刷新4个端点数据,不会触发整页重载:

1. 重构App.js数据拉取逻辑

把分散在4个useEffect中的请求逻辑抽成统一的拉取方法,用Promise.all并行请求所有接口,同时暴露刷新方法传给子组件:

import { useState, useEffect, useCallback } from 'react';
import Tables from './Table';

function App() {
  const [feed, setFeed] = useState({});
  const [feedol, setFeedol] = useState({});
  const [jsonData, setJsonData] = useState({});
  const [azureData, setAzureData] = useState({});
  const [isRefreshing, setIsRefreshing] = useState(false);

  // 统一封装全量数据拉取逻辑
  const fetchAllData = useCallback(async () => {
    setIsRefreshing(true);
    try {
      // 并行拉取4个接口,减少等待时间
      const [feedRes, feedolRes, jsonRes, azureRes] = await Promise.all([
        fetch("/feed").then(res => res.json()),
        fetch("/feed_ol").then(res => res.json()),
        fetch("/json_data").then(res => res.json()),
        fetch("/azure_data").then(res => res.json())
      ]);
      // 批量更新状态,仅触发一次重渲染
      setFeed(feedRes);
      setFeedol(feedolRes);
      setJsonData(jsonRes["archive"][0]);
      setAzureData(azureRes);
    } catch (err) {
      console.error("数据拉取失败:", err);
    } finally {
      setIsRefreshing(false);
    }
  }, []);

  // 组件首次挂载时拉取初始数据
  useEffect(() => {
    fetchAllData();
  }, [fetchAllData]);

  return (
    <div className="App">
      <Tables 
        feed={feed}
        feedol={feedol}
        jsonData={jsonData}
        azureData={azureData}
        refresh={fetchAllData}
        isRefreshing={isRefreshing}
      />
    </div>
  );
}

export default App;

注意:初始state建议设为空对象{}而不是空数组[],避免首次渲染时读取feed.title这类属性报undefined错误。

2. 修改Table.js按钮绑定

把父组件传入的刷新方法绑定到按钮的点击事件上,同时加上加载状态的交互:

import React from "react";
import { Card, Container } from "react-bootstrap";
import { BsArrowClockwise } from "react-icons/bs";
import Cards from "./Cards";

import "./tables.css";
export const Tables = ({ feed, feedol, jsonData, azureData, refresh, isRefreshing }) => {
  return (
    <Container>
    <Cards />
     <Card className="table-card">
      <Card.Header>
         {" "}
        <button 
          type="button" 
          className="refresh-button" 
          onClick={refresh}
          disabled={isRefreshing}
        >
        {" "}
        <BsArrowClockwise className={isRefreshing ? "spin" : ""} />
       </button>{" "}
       OneLogin Outages{" "}
       </Card.Header>
       <Card.Body>
        <table className="table table-bordered">
           <thead>
           <tr>
            <th>Title</th>
            <th>Link</th>
            <th>Date</th>
          </tr>
          </thead>
          <tbody>
            <tr>
             <td>{feedol.title}</td>
             <td>{feedol.link}</td>
             <td>{feedol.updated}</td>
             </tr>
            <tr>
            <td>{}</td>
            <td>{}</td>
            <td>{}</td>
            </tr>
            <tr>
            <td>{jsonData.service_name}</td>
            <td>{jsonData.summary}</td>
            <td>{jsonData.date}</td>
          </tr>
          </tbody>
        </table>
       </Card.Body>
       </Card>
      <Cards />
      <Card className="table-card">
       <Card.Header> Unifi Outages </Card.Header>
       <Card.Body>
         <table className="table table-bordered">
           <thead>
             <tr>
            <th>Title</th>
            <th>Link</th>
            <th>Date</th>
          </tr>
          </thead>
          <tbody>
          <tr>
            <td>{feed.title}</td>
            <td>{feed.link}</td>
            <td>{feed.updated}</td>
          </tr>
          <tr>
            <td>{}</td>
            <td>{}</td>
            <td>{}</td>
          </tr>
          <tr>
            <td>{azureData.title}</td>
            <td>{azureData.link}</td>
            <td>{azureData.updated}</td>
            </tr>
           </tbody>
         </table>
        </Card.Body>
        </Card>
       </Container>
           );
            };

如果需要刷新时图标旋转,在tables.css里加以下样式即可:

.spin {
  animation: spin 1s linear infinite;
}
@keyframes spin {
  from {transform: rotate(0deg);}
  to {transform: rotate(360deg);}
}

避坑说明

  • 按钮必须显式添加type="button",否则在部分场景下会默认触发表单提交导致页面刷新,这是之前出现整页刷新的常见原因之一
  • 所有数据更新走React状态驱动,只会重渲染依赖对应state的组件部分,不会触发整页重载
  • 用Promise.all并行请求接口比原来4个独立useEffect串行发请求速度更快,批量更新state也不会造成多次无意义重渲染
  • 如果后续要加定时器自动刷新,直接在useEffect里写setInterval(fetchAllData, 刷新间隔)即可,不要用window.location.reload()这类硬刷新方法

内容的提问来源于stack exchange,提问作者Carolina D Vallecillo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:27:13