React组件中如何用对象方式管理多个useMutation状态?
如何以对象式方式管理多个useMutation的状态?
问题背景
在React组件中使用多个useMutation时,默认需要通过解构数组来获取mutate函数和状态,重命名状态会导致代码冗余:
// 原有写法 const [get_items, { error, loading, data }] = useMutation(GET_ITEMS); const [add_to_cart, { error: error1, loading: loading1, data: data1 }] = useMutation(ADD_TO_CART);
希望借鉴useQuery的对象式访问方式,通过类似getItemsMutation.loading的点语法直接访问状态,同时保证mutate函数能正常调用。
解决方案
方法1:封装自定义Hook统一处理
自己封装一个Hook,将useMutation返回的数组拆包后整合成单个对象,把mutate函数作为对象的mutate属性,状态直接挂载到对象上:
import { useMutation } from '@apollo/client'; const useMutationObject = (mutation, options) => { const [mutate, state] = useMutation(mutation, options); return { mutate, ...state }; };
使用方式:
// 初始化mutation对象 const getItemsMutation = useMutationObject(GET_ITEMS); const addToCartMutation = useMutationObject(ADD_TO_CART); // 调用mutate函数 const addToCartFunc = async (e, user, item) => { e.preventDefault(); if (user) { addToCartMutation.mutate({ variables: { user, item } }); } }; // 访问状态 if (getItemsMutation.loading || addToCartMutation.loading) { return <div>Loading...</div>; }
方法2:直接组装对象(无需封装Hook)
如果不想额外封装Hook,也可以在使用useMutation时手动将mutate函数和状态对象合并:
import { useMutation } from '@apollo/client'; // 初始化并组装对象 const [getItemsMutate, getItemsState] = useMutation(GET_ITEMS); const getItemsMutation = { mutate: getItemsMutate, ...getItemsState }; const [addToCartMutate, addToCartState] = useMutation(ADD_TO_CART); const addToCartMutation = { mutate: addToCartMutate, ...addToCartState };
使用方式和方法1完全一致,调用addToCartMutation.mutate(...),通过点语法访问loading、error等状态。
原理说明
useMutation默认返回的是数组,第一个元素是mutate函数,第二个是包含loading/error/data的状态对象。数组无法通过点语法访问内部元素的属性,因此需要将数组中的两个元素合并成一个普通对象,才能实现像useQuery那样的对象式访问。
内容的提问来源于stack exchange,提问作者Caleb
相关产品推荐
相关产品推荐

