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
相关产品推荐
相关产品推荐

