如何在组件API请求完成后调用主页面的refreshData()方法
问题描述
我在默认的Home组件中通过以下代码实现props刷新:
const router = useRouter() const refreshData = () => router.replace(router.asPath);
希望在API请求完成后调用refreshData()方法。按钮通过以下方式创建:
import * as functions from "../components/funkcje";
{functions.button(id)}
/components/funckje.tsx
export function button(id:number){ return( <button onClick={() => zmien_stan(0, id)}> Zmien Stan </button> ) }
核心问题:API请求(zmien_stan函数)获取响应后,如何调用主页面的refreshData()?
zmien_stan函数代码:
async function zmien_stan(typ:number, id:number){ const response = await fetch('/api/db', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id, type: typ}) }); if (!response.ok){ throw new Error(response.statusText); } return await response.json(); }
解决方案
以下是几种可行的实现方式,按需选择:
方法1:给按钮传递成功回调
直接将Home组件的refreshData作为参数传入按钮组件,在API请求完成后触发。
步骤1:修改/components/funckje.tsx
更新zmien_stan支持接收成功回调,同时让button函数接收该回调参数:
// 修改zmien_stan,新增onSuccess回调参数 async function zmien_stan(typ:number, id:number, onSuccess?: () => void){ const response = await fetch('/api/db', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id, type: typ}) }); if (!response.ok){ throw new Error(response.statusText); } const data = await response.json(); // 请求成功后执行回调 if (onSuccess) onSuccess(); return data; } // 修改button函数,接收onSuccess参数 export function button(id:number, onSuccess?: () => void){ return( <button onClick={() => zmien_stan(0, id, onSuccess)}> Zmien Stan </button> ) }
步骤2:修改Home组件的按钮调用
将refreshData传入按钮:
{functions.button(id, refreshData)}
方法2:在Home组件内处理完整逻辑
把点击事件的处理逻辑移到Home组件,按钮只负责渲染,降低组件耦合度。
步骤1:修改/components/funckje.tsx
让按钮接收点击事件回调:
export function button(id:number, onClick: () => void){ return( <button onClick={onClick}> Zmien Stan </button> ) }
步骤2:修改Home组件
导入zmien_stan并在点击事件中完成请求+刷新:
import { zmien_stan } from "../components/funkcje"; // 定义点击处理函数 const handleButtonClick = async () => { try { await zmien_stan(0, id); refreshData(); } catch (err) { // 可在此添加错误处理逻辑,比如提示用户 console.error('请求失败:', err); } } // 调用按钮时传入点击事件 {functions.button(id, handleButtonClick)}
方法3:全局状态管理(复杂场景适用)
如果应用中有多个组件需要触发刷新逻辑,可以用全局状态管理方案(如Zustand、Context):
示例:用Zustand实现
- 创建状态管理store:
// /store/refreshStore.ts import { create } from 'zustand'; const useRefreshStore = create((set) => ({ shouldRefresh: false, triggerRefresh: () => set({ shouldRefresh: true }), resetRefresh: () => set({ shouldRefresh: false }), })); export default useRefreshStore;
- 在Home组件中监听刷新状态:
import useRefreshStore from '../store/refreshStore'; const Home = () => { const router = useRouter(); const { shouldRefresh, resetRefresh } = useRefreshStore(); useEffect(() => { if (shouldRefresh) { router.replace(router.asPath); resetRefresh(); } }, [shouldRefresh, router, resetRefresh]); // ...其他组件代码 }
- 在
zmien_stan中触发全局刷新:
import useRefreshStore from '../store/refreshStore'; async function zmien_stan(typ:number, id:number){ const response = await fetch('/api/db', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id, type: typ}) }); if (!response.ok){ throw new Error(response.statusText); } const data = await response.json(); // 触发全局刷新 useRefreshStore.getState().triggerRefresh(); return data; }
内容的提问来源于stack exchange,提问作者PrzepalonyDecybel
相关产品推荐
相关产品推荐

