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

React Admin自定义路由中刷新按钮无法触发Fetch函数问题

解决React Admin导航栏刷新按钮不触发自定义fetch的问题

你的自定义页面中,useEffect依赖为空数组,仅在组件首次挂载时执行fetchResults。而React Admin导航栏的默认刷新按钮,只会触发数据提供者(Data Provider)的刷新动作,不会自动调用你自定义的拉取函数,因此点击刷新时不会重新获取数据。同时你原代码中fetchResults拿到数据后没有调用setData,这也会导致组件无法更新数据。

方案一:利用React Admin的刷新状态监听

React Admin提供了useGetRefreshState钩子,可以监听全局的刷新状态变化。当点击导航栏的刷新按钮时,这个状态会更新,我们可以把它加入useEffect的依赖项,触发重新拉取数据。

修改后的代码:

import { useParams, useNavigate } from 'react-router-dom';
import { useState, useEffect } from 'react';
import { Title, useGetRefreshState } from 'react-admin';
import { DataGrid } from '@mui/x-data-grid';

export const MyCustomPage= () => {
  const navigate = useNavigate();
  const params = useParams();
  const id = params.id;
  const [data, setData] = useState();
  // 获取全局刷新状态
  const isRefreshing = useGetRefreshState();
  
  const fetchResults = async () => {
    try {
      const { data: fetchedData } = await getAnswers(id);
      // 必须调用setData更新组件状态
      setData(fetchedData);
    } catch (e) {
      // 添加错误处理逻辑,比如提示用户拉取失败
      console.error('拉取数据失败:', e);
    }
  };

  // 当id变化或刷新状态变化时,重新拉取数据
  useEffect(() => {
    fetchResults();
  }, [id, isRefreshing]);


  return (
    <>
      <Title title={`${calculator.name} results`} />
      <DataGrid columns={data} />
    </>
  );
};

方案二:自定义导航栏刷新按钮

如果不想依赖React Admin的全局刷新机制,可以自定义导航栏的刷新按钮,直接绑定你的fetchResults函数。

步骤1:创建自定义AppBar

import { AppBar, RefreshIcon } from 'react-admin';
import { IconButton } from '@mui/material';
import { useRefreshContext } from './RefreshContext'; // 自定义的Context

const CustomAppBar = (props) => {
  // 从Context中获取自定义的拉取函数
  const fetchResults = useRefreshContext();
  
  return (
    <AppBar {...props}>
      {/* 保留React Admin默认的AppBar内容 */}
      <div style={{ marginLeft: 'auto' }}>
        <IconButton onClick={fetchResults} color="inherit">
          <RefreshIcon />
        </IconButton>
      </div>
    </AppBar>
  );
};

步骤2:创建RefreshContext

import { createContext, useContext } from 'react';

const RefreshContext = createContext();

export const useRefreshContext = () => useContext(RefreshContext);

export const RefreshProvider = ({ children, fetchResults }) => (
  <RefreshContext.Provider value={fetchResults}>
    {children}
  </RefreshContext.Provider>
);

步骤3:在页面中使用Provider并配置自定义布局

import { useParams, useNavigate } from 'react-router-dom';
import { useState, useEffect } from 'react';
import { Title, Layout } from 'react-admin';
import { DataGrid } from '@mui/x-data-grid';
import { RefreshProvider } from './RefreshContext';
import { CustomAppBar } from './CustomAppBar';

// 自定义布局
const CustomLayout = (props) => (
  <Layout {...props} appBar={CustomAppBar} />
);

export const MyCustomPage= () => {
  const navigate = useNavigate();
  const params = useParams();
  const id = params.id;
  const [data, setData] = useState();
  
  const fetchResults = async () => {
    try {
      const { data: fetchedData } = await getAnswers(id);
      setData(fetchedData);
    } catch (e) {
      console.error('拉取数据失败:', e);
    }
  };

  useEffect(() => {
    fetchResults();
  }, [id]);

  // 使用Provider传递fetchResults到自定义AppBar
  return (
    <RefreshProvider fetchResults={fetchResults}>
      <>
        <Title title={`${calculator.name} results`} />
        <DataGrid columns={data} />
      </>
    </RefreshProvider>
  );
};

// 在路由配置中使用自定义布局
// <Route path="/my-custom-page/:id" element={<MyCustomPage />} layout={CustomLayout} />

内容的提问来源于stack exchange,提问作者Drem Edys

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:18:33