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

React Hooks中如何在特定动作后创建RxJS订阅并取消订阅?

如何在特定动作触发RxJS订阅并正确取消

要实现表单提交成功后启动RxJS倒计时,同时妥善处理订阅取消(避免内存泄漏、重复订阅),可以按以下方式修改代码:

核心思路

  • 用useRef持久存储订阅实例,方便后续取消
  • 组件卸载时自动清理订阅
  • 再次触发提交时,先取消旧订阅再创建新的
  • 使用函数式更新状态避免闭包问题

修改后的完整代码

import { interval, Subscription } from 'rxjs';
import { take } from 'rxjs/operators';
import { useState, useEffect, useRef } from 'react';
// 导入你的sendCode和message组件

const YourComponent = () => {
  const [timing, setTiming] = useState<number>(60);
  // 用useRef保存订阅实例,初始为null
  const countdownSubscription = useRef<Subscription | null>(null);

  // 组件卸载时强制取消订阅,防止内存泄漏
  useEffect(() => {
    return () => {
      countdownSubscription.current?.unsubscribe();
    };
  }, []);

  const sendCodeOnceSubmit = async (phone: number) => {
    // 先取消之前的倒计时(如果存在),避免多个倒计时同时运行
    countdownSubscription.current?.unsubscribe();

    const res = await sendCode(phone);
    if (res.code !== 200) {
      message.error(`${res.message}`);
      // 请求失败时重置倒计时
      setTiming(60);
    } else {
      // 重置倒计时初始值
      setTiming(60);
      // 创建新的订阅并保存到useRef中
      countdownSubscription.current = interval(1000)
        .pipe(take(60)) // 只取60次值,对应60秒倒计时
        .subscribe({
          next: () => {
            // 用函数式更新获取最新状态,避免闭包问题
            setTiming(prevTiming => prevTiming - 1);
          },
          complete: () => {
            // 倒计时结束后重置状态,并清空订阅引用
            setTiming(60);
            countdownSubscription.current = null;
          }
        });
    }
  };

  // 组件其他逻辑...

  return (
    // 你的表单JSX...
  );
};

export default YourComponent;

关键细节说明

  1. useRef存储订阅:useRef的.current属性在组件生命周期内不会被重置,能稳定保存订阅实例,不会像普通变量那样每次渲染都重新初始化。
  2. 组件卸载清理:useEffect的返回函数会在组件卸载时执行,这里调用unsubscribe()确保订阅被正确取消,防止内存泄漏。
  3. 重复提交处理:每次触发sendCodeOnceSubmit时先取消旧订阅,避免同一时间存在多个倒计时流,导致状态混乱。
  4. 函数式更新状态:直接用setTiming(prev => prev - 1),而不是依赖外部的timing变量,解决了闭包导致的状态更新滞后问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:54:18