You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅在按钮点击时调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 23:32:04