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

React-query中mutation成功后跳转页面避免内存泄漏的方法

React-query Mutation后跳转页面的内存泄漏警告解决方法

出现这个警告的核心原因是:mutation异步操作完成后,当前组件已经被卸载,但回调里仍在尝试更新组件状态或执行后续操作。以下是几种实用的解决方式:


1. 通过isSuccess结合useEffect触发跳转

利用React-query提供的isSuccess状态,在组件挂载状态下执行跳转逻辑:

import { useMutation } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';

const YourComponent = () => {
  const navigate = useNavigate();
  const { mutate, isSuccess } = useMutation(yourMutationFunction);

  // 监听isSuccess状态,仅在组件挂载时执行跳转
  useEffect(() => {
    if (isSuccess) {
      navigate('/target-page');
    }
  }, [isSuccess, navigate]);

  const handleSubmit = () => {
    mutate(yourData);
  };

  return <button onClick={handleSubmit}>提交</button>;
};

2. 在onSuccess回调中检查组件挂载状态

用useRef跟踪组件是否挂载,避免卸载后执行状态更新或跳转:

import { useMutation } from '@tanstack/react-query';
import { useNavigate, useRef, useEffect } from 'react-router-dom';

const YourComponent = () => {
  const navigate = useNavigate();
  const isMounted = useRef(true);

  const { mutate } = useMutation(yourMutationFunction, {
    onSuccess: () => {
      // 仅在组件挂载时执行后续操作
      if (isMounted.current) {
        navigate('/target-page');
      }
    }
  });

  // 组件卸载时标记为未挂载
  useEffect(() => {
    return () => {
      isMounted.current = false;
    };
  }, []);

  const handleSubmit = () => {
    mutate(yourData);
  };

  return <button onClick={handleSubmit}>提交</button>;
};

3. 用mutateAsync结合挂载检查

如果习惯用async/await调用mutation,可结合挂载状态判断:

import { useMutation } from '@tanstack/react-query';
import { useNavigate, useRef, useEffect } from 'react-router-dom';

const YourComponent = () => {
  const navigate = useNavigate();
  const isMounted = useRef(true);
  const { mutateAsync } = useMutation(yourMutationFunction);

  const handleSubmit = async () => {
    try {
      await mutateAsync(yourData);
      // 确认组件仍挂载再跳转
      if (isMounted.current) {
        navigate('/target-page');
      }
    } catch (err) {
      // 错误处理逻辑
    }
  };

  useEffect(() => {
    return () => {
      isMounted.current = false;
    };
  }, []);

  return <button onClick={handleSubmit}>提交</button>;
};

4. 取消未完成的异步请求(适用于可取消的请求)

如果你的mutation基于可取消的请求(比如Axios),可在组件卸载时主动取消:

import { useMutation } from '@tanstack/react-query';
import { useNavigate, useEffect } from 'react-router-dom';
import axios from 'axios';

const YourComponent = () => {
  const navigate = useNavigate();

  const { mutate } = useMutation((data) => {
    const source = axios.CancelToken.source();
    const request = axios.post('/api/your-endpoint', data, {
      cancelToken: source.token
    });
    // 给请求附加取消方法
    request.cancel = () => source.cancel('组件已卸载,取消请求');
    return request;
  }, {
    onSuccess: () => navigate('/target-page')
  });

  // 组件卸载时取消当前mutation请求
  useEffect(() => {
    return () => {
      if (mutate.cancel) {
        mutate.cancel();
      }
    };
  }, [mutate]);

  const handleSubmit = () => {
    mutate(yourData);
  };

  return <button onClick={handleSubmit}>提交</button>;
};

内容的提问来源于stack exchange,提问作者Foyez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 10:45:34