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

Razorpay React中链式dispatch HTTP请求报错Invalid Hook Call

问题

刚接触Redux和React,正在集成Razorpay的订阅功能。单独dispatch verifySignature接口完全正常,但链式调用dispatch updateSubscriptionStatus时触发Invalid Hook Call错误。移除内层的updateSubscriptionStatus dispatch后功能恢复正常,需要解决这个链式dispatch的问题。


代码片段

组件代码

const SubscriptionForm: FC<ISubscriptionForm> = ({ planId, totalCount }) => {

  const { data: user, isFetching } = useAppSelector((store) => store.user.details);

  const dispatch = useAppDispatch();
  const [Razorpay] = useRazorpay();

  const handlePayment = async (subscription_id: any, userDetails: { name: string; email: string; phone: string}) => {


    const options: any = {
      key: process.env.REACT_APP_RAZORPAY_ID,
      amount: "500",
      currency: "USD",
      name: "Test App",
      description: "Test Transaction",
      image: Logo,
      subscription_id: subscription_id,
      handler: (razaorpayResponse: {
        razorpay_payment_id: any;
        razorpay_subscription_id: any;
        razorpay_signature: any;
      }) => {
        dispatch(SubscriptionRestService.verifySignature({ razaorpayResponse}))
          .then((response) => {
            if (SubscriptionRestService.verifySignature.fulfilled.match(response)) {
              console.log("Success:", response);
              dispatch(SubscriptionRestService.updateSubscriptionStatus({ subscriptionId: subscription_id, status: "active" }))
                .then((response) => {
                  if (SubscriptionRestService.updateSubscriptionStatus.fulfilled.match(response)) {
                    console.log("Success:", response);
                    toast.success("Subscription was activated successfully");
                  } else {
                    console.error("Error:", response);
                    toast.error("Subscription activation may have failed. Please contact support if payment was deducted");
                  }
                })
                .catch((error) => {
                  console.error("Error:", error);
                });
              toast.success("Subscription was activated successfully");
            } else {
              console.error("Error:", response);
              toast.error("Subscription may have failed. Please contact support if payment was deducted");
            }
          })
          .catch((error) => {
            console.error("Error:", error);
          });
      },
      theme: {
        color: "#e9e6e6",
      },
      prefill: {
        name: userDetails.name,
        email: userDetails.email,
        contact: userDetails.phone,
      }
    };
    const rzp1 = new Razorpay(options);

    rzp1.open();
  }

AsyncThunk代码

const verifySignature = createAsyncThunk(
  'subscription/verify_signature',
  async (args:{razaorpayResponse: {
    razorpay_payment_id: any;
    razorpay_subscription_id: any;
    razorpay_signature: any;
  }}, { rejectWithValue }) => {
    try {
      return (await HttpClient.post('/payment/verify-signature', args.razaorpayResponse)).data;
    } catch (error: any) {
      return rejectWithValue(error.message);
    }
});

const updateSubscriptionStatus = createAsyncThunk(
  'subscription/update_status',
  async (args: { subscriptionId: any, status: any }, { rejectWithValue }) => {
    try {
      return (await HttpClient.post('/payment/update-subscription-status', args)).data;
    } catch (error: any) {
      return rejectWithValue(error.message);
    }
});

解决方案

1. 排查HttpClient的Hook使用问题

Invalid Hook Call错误核心原因是在非React组件/自定义Hook的函数中调用了React Hooks。检查你的HttpClient实例,如果它内部使用了useState、useSelector这类Hook,就会触发错误——因为AsyncThunk的执行环境不在React渲染周期内,不能直接调用Hook。

修复方式:移除HttpClient内的Hook逻辑,改用AsyncThunk提供的getState参数获取Redux store中的数据。比如需要请求头token时:

const updateSubscriptionStatus = createAsyncThunk(
  'subscription/update_status',
  async (args: { subscriptionId: any, status: any }, { rejectWithValue, getState }) => {
    try {
      // 从Redux store获取token,而非在HttpClient内部用Hook
      const token = (getState() as RootState).user.token;
      return (await HttpClient.post(
        '/payment/update-subscription-status', 
        args, 
        { headers: { Authorization: `Bearer ${token}` } }
      )).data;
    } catch (error: any) {
      return rejectWithValue(error.message);
    }
});

2. 确认useAppDispatch类型定义正确

错误也可能来自useAppDispatch的类型错误,确保在store文件中正确定义:

// store.ts
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();

3. 改用async/await简化调用逻辑(可选)

把链式then调用改成async/await,代码更清晰,也能避免潜在的上下文问题:

handler: async (razaorpayResponse) => {
  try {
    const verifyResponse = await dispatch(SubscriptionRestService.verifySignature({ razaorpayResponse }));
    if (SubscriptionRestService.verifySignature.fulfilled.match(verifyResponse)) {
      console.log("Verify Success:", verifyResponse);
      const updateResponse = await dispatch(SubscriptionRestService.updateSubscriptionStatus({ subscriptionId: subscription_id, status: "active" }));
      if (SubscriptionRestService.updateSubscriptionStatus.fulfilled.match(updateResponse)) {
        console.log("Update Success:", updateResponse);
        toast.success("Subscription was activated successfully");
      } else {
        console.error("Update Error:", updateResponse);
        toast.error("Subscription activation may have failed. Please contact support if payment was deducted");
      }
    } else {
      console.error("Verify Error:", verifyResponse);
      toast.error("Subscription may have failed. Please contact support if payment was deducted");
    }
  } catch (error) {
    console.error("Handler Error:", error);
  }
}

内容的提问来源于stack exchange,提问作者not-a-bot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:05:32