如何仅在按钮点击时调用React Query的useMutation
问题:如何实现仅在按钮点击时触发自定义useMutation?
用户疑问
- 组件挂载时自定义
useMutation自动执行,希望仅在按钮点击且存在有效坐标数据时触发,无数据时不执行或抛出错误; - 不确定是否正确处理
useMutation返回的isLoading、isError、isSuccess状态。
自定义useMutation hook代码
export const constructOmgevingscheckPostRequest = (coordinates: string) => { console.log( 'coordinates inside constructOmgevingscheckPostRequest', coordinates, ); return { verzoekAard: 'ARC', geometrie: coordinates, }; }; export async function getOmgevingscheckData(coordinates: string) { console.log('coordinates inside getOmgevingscheckResult', coordinates); const { data: response } = await omgevingscheckApi.post( '/rs/v1/omgevingscheck', constructOmgevingscheckPostRequest(coordinates), ); return response; } export function useOmgevingscheckMutation(coordinates: any) { return useMutation(['omgevingscheck', { coordinates }], () => getOmgevingscheckData(coordinates), ); }
组件使用代码
import { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { type IOmgevingscheckThema } from '../../types/IOmgevingscheckData'; import { Loading } from '@/components/Loading'; import { ErrorAlert } from '@/features/error/components'; import { useOmgevingscheckMutation } from '@/api'; import { usePolygonWktString } from '../../context/PolygonContext'; export function DesktopLayout() { const [step, setStep] = useState<number>(0); const { t } = useTranslation('app'); const polygonWktString = usePolygonWktString(); const useMutation = useOmgevingscheckMutation( polygonWktString?.polygonWktString, ); const handleOmgevingscheckUitvoeren = () => { console.log( 'polygonWktString from store', polygonWktString?.polygonWktString, ); useMutation.mutate(); setStep(step + 1); }; useEffect(() => { if (useMutation.isSuccess) { // console.log('data', useMutation.data); } }, [useMutation.isSuccess, useMutation.isError]); return ( <> {useMutation.isLoading && ( // Loading Component )} {useMutation.isError ? ( // Error Component ) : null} {step === 0 && ( <DesktopStepOne omgevingscheckUitvoeren={handleOmgevingscheckUitvoeren} isDisabled={polygonWktString?.polygonWktString ? false : true} /> )} {step === 1 && useMutation.isSuccess && ( // Component showing all of the data from the useMutation.data </div> )} </> ); }
解决方案
1. 修正自定义hook,避免自动执行
问题根源在于自定义hook提前绑定了coordinates,若误用useQuery(而非useMutation)也会导致自动执行。调整如下:
修改自定义useOmgevingscheckMutation:
export function useOmgevingscheckMutation() { return useMutation(['omgevingscheck'], (coordinates: string) => { // 前置校验数据有效性 if (!coordinates) { throw new Error('坐标数据不能为空'); } return getOmgevingscheckData(coordinates); }); }
组件调用方式调整:
export function DesktopLayout() { const [step, setStep] = useState<number>(0); const { t } = useTranslation('app'); const polygonWktString = usePolygonWktString(); // 初始化hook,此时不会触发请求 const mutation = useOmgevingscheckMutation(); const handleOmgevingscheckUitvoeren = () => { const coords = polygonWktString?.polygonWktString; // 点击时先校验数据 if (!coords) { alert('请先选择有效的区域'); return; } // 仅在点击时调用mutate触发请求 mutation.mutate(coords, { onSuccess: () => { // 请求成功后再跳转到下一步 setStep(prev => prev + 1); }, onError: (err) => { console.error('请求失败:', err); // 可在这里添加错误提示逻辑 } }); }; return ( <> {/* 根据状态直接渲染对应组件,无需额外useEffect */} {mutation.isLoading && <Loading />} {mutation.isError && <ErrorAlert message={mutation.error?.message} />} {step === 0 && ( <DesktopStepOne omgevingscheckUitvoeren={handleOmgevingscheckUitvoeren} isDisabled={!polygonWktString?.polygonWktString} /> )} {step === 1 && mutation.isSuccess && ( <div> {/* 展示请求返回的数据 */} </div> )} </> ); }
2. 状态处理优化
- 无需用
useEffect监听isSuccess/isError,直接在组件渲染阶段根据状态值展示对应UI即可; - 利用
mutate方法的onSuccess/onError回调处理请求后的逻辑,确保只有请求成功才更新步骤; - 状态判断逻辑保持简洁,直接通过
mutation.isLoading/isError/isSuccess控制组件显示。
内容的提问来源于stack exchange,提问作者intercoder
相关产品推荐
相关产品推荐

