React Hook useGetCompanyAvatar回调调用报错,如何更新企业头像?
问题:上传企业头像后调用自定义Hook更新头像报错
我实现了一个上传企业主头像的PUT请求,代码如下:
if (fileList.length) { console.log(fileList[0]); Api.companies .putCompanyAvatar( company?.id as string, new Blob([fileList[0].originFileObj as any], { type: 'application/jpeg' }), ) .then(() => { setFileList([]); client.invalidateQueries(['company-avatar']); setCompanyAv(useGetCompanyAvatar()); }); }
执行后收到错误提示:
React Hook "useGetCompanyAvatar" cannot be called inside a callback.
自定义Hook useGetCompanyAvatar 的代码如下:
import { useQuery } from "@tanstack/react-query"; import { Api } from "../index"; const useGetCompanyAvatar = ( companyId: string | undefined, ) => { const query = () => { return Api.companies.getCompanyAvatar(companyId); }; const { isLoading, data: companyAvatar } = useQuery( ["company-avatar"], query, { select: (r) => URL.createObjectURL(new Blob([r?.data as any], { type: r?.headers['content-type'] })) } ); return { isLoading, companyAvatar, }; }; export default useGetCompanyAvatar;
请问为什么无法通过这种方式获取并更新新的当前头像?
原因分析
- 违反React Hook核心规则:React Hook必须在组件的顶层作用域调用,不能嵌套在回调、循环等函数内部。你在
then回调里调用useGetCompanyAvatar,直接违反了这条规则,所以触发报错。 - react-query的自动更新已生效:你已经调用了
client.invalidateQueries(['company-avatar']),这会让react-query标记该查询为失效,自动重新发起请求获取最新头像数据,完全不需要手动调用自定义Hook去重复获取。
正确实现方式
只需要在组件顶层调用useGetCompanyAvatar获取头像数据,上传完成后仅清理文件列表并触发查询失效即可,react-query会自动更新头像:
// 在组件顶层调用自定义Hook,获取头像数据 const { companyAvatar, isLoading } = useGetCompanyAvatar(company?.id); // 上传逻辑函数 const handleAvatarUpload = () => { if (fileList.length) { Api.companies .putCompanyAvatar( company?.id as string, new Blob([fileList[0].originFileObj as any], { type: 'application/jpeg' }), ) .then(() => { setFileList([]); // 触发查询失效,react-query自动重新请求最新头像 client.invalidateQueries(['company-avatar']); }); } };
修改后,invalidateQueries执行时,useGetCompanyAvatar中的useQuery会自动重新拉取最新头像,companyAvatar会同步更新,组件也会自动渲染新头像,无需手动调用setCompanyAv。
内容的提问来源于stack exchange,提问作者Metgher Andrei
相关产品推荐
相关产品推荐

