使用axios发送POST请求时如何在组件中获取Redux dispatch返回的响应数据
核心错误点
- React Hook 有严格的调用位置限制:
useEffect只能在组件顶层、自定义Hook顶层调用,写在handleSubmit事件回调内部直接违反规则,必然报错。 - 你当前直接解构
dispatch(paymentInfo(...))返回值拿clientSecret、backendError的写法不成立:paymentInfo是redux-thunk异步action,不加await的情况下,代码执行到这一行时接口请求还没完成,拿不到响应结果;就算加了await,thunk默认不会把响应数据直接作为dispatch返回值返回,你解构出来的是undefined。 - 你已经在
paymentInfoReducer里把接口返回的data存在了state的info字段下,只要按Redux的标准流程取状态、监听状态变化即可拿到数据。
实现方案
第一步:组件顶层接入Redux状态
在PlaceOrderScreen组件的最外层(不要写在任何函数、条件判断内部),通过useSelector取出存在Redux里的支付相关状态:
import { useDispatch, useSelector } from 'react-redux'; // 保留你原有的其他import,比如stripe相关、组件相关依赖 const PlaceOrderScreen = () => { const dispatch = useDispatch(); // 对应reducer里的loading、error、info字段,info就是PAYMENT_SUCCESS时存的接口响应data const { loading, error: backendError, info: paymentResponse } = useSelector(state => state.paymentInfo); // 保留你原有的stripe、elements、userId等变量声明
第二步:修正handleSubmit逻辑
去掉原来直接从dispatch返回值解构的错误写法,给dispatch加await等待异步action执行完成即可,后续Stripe支付逻辑不要写在handleSubmit里:
const handleSubmit = async (e) => { e.preventDefault(); if (!stripe || !elements) { return; } const paymentMethodType = 'card'; const currency = 'usd'; // 等待异步请求dispatch完成 await dispatch(paymentInfo(paymentMethodType, currency, userId)); };
第三步:顶层写useEffect监听状态变化执行后续逻辑
同样在组件顶层写useEffect,监听支付状态变化,拿到接口返回结果后再执行Stripe确认支付的逻辑:
useEffect(() => { // 接口返回错误直接打印退出 if (backendError) { console.log(backendError); return; } // 拿到接口返回的clientSecret后,再调用stripe确认支付 if (paymentResponse?.clientSecret) { console.log('Client secret returned'); console.log(paymentResponse.clientSecret); const handleStripeConfirm = async () => { const {error: stripeError, paymentIntent} = await stripe.confirmCardPayment( paymentResponse.clientSecret, { payment_method: { card: elements.getElement(CardElement), billing_details: { name: 'Jenny Rosen', }, }, } ); // 后续自行处理stripeError、paymentIntent结果即可 }; handleStripeConfirm(); } // 数组里是effect的依赖项,用到的外部值都要加进去 }, [backendError, paymentResponse, stripe, elements]);
可选优化
你当前reducer里info的初始值设为了空数组[],但接口返回的支付响应是对象类型,建议改成null避免类型判断异常:
// paymentReducers.js export const paymentInfoReducer = (state = { info: null }, action) => { switch (action.type) { case PAYMENT_REQUEST: return { ...state, loading: true }; case PAYMENT_SUCCESS: return { ...state, loading: false, info: action.payload }; case PAYMENT_FAIL: return { ...state, loading: false, error: action.payload }; default: return state; } };
如果你不需要把支付响应数据全局共享,也可以直接修改paymentInfo thunk方法,在请求结束后把data return出去,这样await dispatch(...)就能直接拿到返回值,不需要走useEffect监听,但既然你已经把数据存在Redux里,上面的方案更符合Redux的使用规范。
内容的提问来源于stack exchange,提问作者pelotador.1
相关产品推荐
相关产品推荐

