封装useSWRMutation后data/error/isMutating未正常赋值的问题
问题分析与解决方案
你的useSWRMutation返回的data、error、isMutating始终未被赋值,但trigger能正常返回结果,核心原因是SWR无法将请求结果存入内部缓存或fetcher函数的签名/参数不符合要求,导致组件无法感知状态变化。
可能的原因及对应解决方法
1. Fetcher函数签名不匹配
useSWRMutation要求fetcher必须接收两个参数:第一个是传入的key,第二个是trigger调用时的参数。如果你的postWithAxiosFunction只接收单个参数,会导致参数传递异常,虽然可能偶然返回结果,但SWR无法正确更新状态。
解决方法:修正fetcher函数的签名,即使不需要使用key参数也要显式声明:
// 正确的fetcher示例 const postWithAxiosFunction = async (key: string, params: useParams) => { const response = await axios.post(key, params); // 确保返回后端响应数据,而非AxiosResponse对象 return response.data as VerifiedEmailResponse; };
2. 参数不可序列化导致缓存失败
如果useParams类型包含不可序列化的内容(比如函数、Symbol、循环引用对象),SWR无法生成有效的缓存键,因此无法将fetcher的结果存入缓存,data、error等状态始终保持初始值。
解决方法:
- 移除
useParams中的不可序列化属性,只保留基本类型、普通对象、数组等可序列化内容; - 如果必须保留不可序列化属性,拆分参数:仅将可序列化部分传入
trigger,在execFunction中处理不可序列化逻辑:// 拆分出可序列化的参数类型 type SerializableParams = Omit<useParams, "onSuccess">; const execFunction = useCallback(async () => { // 提取可序列化参数 const serializableParams = { ...params } as SerializableParams; delete serializableParams.onSuccess; const result = await trigger(serializableParams); // 执行原本的不可序列化逻辑 params.onSuccess?.(); return result.user_email; }, [params, trigger]);
3. SWR版本过低
旧版本的useSWRMutation可能不支持返回data、isMutating等状态字段,确保你的SWR版本在1.0.0及以上。
解决方法:升级SWR
npm install swr@latest # 或 yarn add swr@latest
验证方法
在execFunction中直接打印状态,确认trigger调用后是否更新:
const execFunction = useCallback(async () => { console.log("触发前状态:", { data, isMutating }); const result = await trigger(params); console.log("触发后状态:", { data, isMutating }); return result.user_email; }, [params, trigger]);
如果触发后data仍为undefined,则大概率是参数不可序列化或fetcher签名问题;如果data有值但useEffect未触发,需检查组件是否被React.memo包裹且依赖项设置错误。
内容的提问来源于stack exchange,提问作者puntolino
相关产品推荐
相关产品推荐

