使用React自定义Hook更新UI时删除用户重拉列表及加载态处理问题
问题根因
- 违反React Hook调用规则:Hook仅可在组件顶层作用域或自定义Hook内部调用,你在deleteUser事件回调中调用useFetch的写法本身不符合规范,自然无法拿到回调外的状态。
- 现有useFetch设计不完善:未将内部的fetchData方法暴露给外部调用方,无法手动触发数据重新拉取。同时useCallback的依赖项缺少params,参数更新时无法触发请求更新。
- 删除操作没有独立的状态管理:删除属于提交类操作,和拉取列表的查询类操作要分开管理状态,才能在渲染层读取删除中的状态展示加载器。
修复后的代码
调整useFetch实现
import { useState, useCallback, useEffect } from 'react'; export interface APIStatus { status: 'loading' | 'error' | 'done'; } // 泛型支持自定义返回数据类型 export const useFetch = <T = any>(api: (params: any) => Promise<{data: T}>, params: any) => { const [data, setData] = useState<T[]>([]); const [apiStatus, setApiStatus] = useState<APIStatus>({ status: 'loading' }); const [isSignedIn] = getSignInStatus(); // 依赖项补上params,参数变化时自动更新请求方法 const fetchData = useCallback(async () => { setApiStatus({ status: 'loading' }); try { const {data} = await api(params); setData(data); setApiStatus({ status: 'done' }); } catch (err) { setApiStatus({ status: 'error' }); } }, [api, params]); useEffect(() => { if (isSignedIn) fetchData(); }, [isSignedIn, fetchData]); // 暴露手动刷新方法给外部 return { apiStatus, data, refetch: fetchData }; };
调整App组件实现
// App.tsx import { useState } from 'react'; export const App: React.FC = () => { const { apiStatus: listStatus, data: userList, refetch: refetchUsers } = useFetch(apis.fetchUsers, "limit=100"); // 独立维护删除操作的状态 const [deleteStatus, setDeleteStatus] = useState<APIStatus>({ status: 'done' }); const deleteUser = async (id: string) => { setDeleteStatus({ status: 'loading' }); try { await apis.deleteUser(`id=${id}`); // 删除成功后重新拉取最新用户列表 await refetchUsers(); setDeleteStatus({ status: 'done' }); } catch (err) { setDeleteStatus({ status: 'error' }); } } return( <> {/* 列表加载/删除操作中都可以展示加载器,可按需调整为单条记录的加载效果 */} {listStatus.status === 'loading' || deleteStatus.status === 'loading' ? <ShowLoader /> : userList.map(user => <div key={user.id} onClick={() => deleteUser(user.id)}> {user.name} </div>) } </> ) }
实现说明
- 调整后的useFetch主动暴露refetch方法,删除操作成功后直接调用即可拉取最新的用户列表
- 单独为删除操作维护deleteStatus状态,渲染层可以直接读取该状态判断是否需要展示加载器,也可拓展为单条记录的删除中状态,仅给被点击的用户条目加加载效果
- 补全了useFetch内部useCallback的依赖项,避免参数更新后请求不生效的隐藏问题
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

