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
相关产品推荐
相关产品推荐

