如何在同一组件中使用RTK Query的查询与Mutation状态hooks
在同一组件中使用RTK Query的查询与Mutation Hooks实现个人资料编辑功能
核心结论
完全可以在同一组件中多次使用RTK Query的各类状态hooks(查询、Mutation),每个hook返回的状态(如isLoading、isSuccess、error)都是独立隔离的,不会互相影响。
具体实现示例
假设你的API切片已经定义了useGetProfileQuery和useUpdateProfileMutation,以下是组件的完整实现思路:
import { useState, useEffect } from 'react'; import { useGetProfileQuery, useUpdateProfileMutation } from './api/profileApi'; function ProfileEditor() { // 获取个人资料的查询hook,重命名状态避免冲突 const { data: profileData, isLoading: fetchIsLoading, error: fetchError, isError: fetchIsError } = useGetProfileQuery('profile'); // 更新个人资料的Mutation hook,重命名状态区分查询状态 const [updateUser, { isLoading: updateIsLoading, isSuccess: updateIsSuccess, error: updateError, isError: updateIsError }] = useUpdateProfileMutation(); // 本地状态存储编辑中的表单数据 const [formData, setFormData] = useState({}); // 查询到资料后初始化表单 useEffect(() => { if (profileData) { setFormData(profileData); } }, [profileData]); // 表单输入变更处理 const handleInputChange = (e) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; // 提交更新请求 const handleSubmit = async (e) => { e.preventDefault(); try { await updateUser(formData).unwrap(); // 成功后重置表单为原始数据 setFormData(profileData); } catch (err) { // 可手动补充错误逻辑,RTK Query已返回error状态供渲染 } }; // 初始加载状态:显示获取资料的加载指示器 if (fetchIsLoading) { return <div>正在加载个人资料...</div>; } // 查询错误状态:显示获取资料的错误提示 if (fetchIsError) { return <div>加载失败:{fetchError?.message}</div>; } return ( <form onSubmit={handleSubmit}> {/* 更新成功提示 */} {updateIsSuccess && <div className="success">个人资料更新成功!</div>} {/* 更新错误提示 */} {updateIsError && <div className="error">更新失败:{updateError?.message}</div>} <div> <label>用户名:</label> <input type="text" name="username" value={formData.username || ''} onChange={handleInputChange} disabled={updateIsLoading} /> </div> <div> <label>邮箱:</label> <input type="email" name="email" value={formData.email || ''} onChange={handleInputChange} disabled={updateIsLoading} /> </div> {/* 提交按钮:根据更新状态切换显示文本与禁用状态 */} <button type="submit" disabled={updateIsLoading}> {updateIsLoading ? '更新中...' : '保存更改'} </button> </form> ); } export default ProfileEditor;
关键细节说明
- 状态重命名:通过ES6对象重命名语法(
isLoading: fetchIsLoading),避免查询和Mutation返回的同名状态变量冲突。 - 状态隔离:
fetchIsLoading仅对应获取资料的请求状态,updateIsLoading对应更新请求的状态,二者完全独立,互不干扰。 - 表单状态管理:使用本地
useState存储编辑中的表单数据,禁止直接修改RTK Query返回的缓存数据(该数据为不可变结构)。 - 状态联动:更新请求触发时,禁用输入框与提交按钮,避免重复提交;更新成功后重置表单,保持数据一致性。
内容的提问来源于stack exchange,提问作者Raghuram
相关产品推荐
相关产品推荐

