Redux异步Action的Promise回调中执行setState报错如何解决
报错原因
- 未捕获Promise拒绝:你在Action返回的Promise中请求失败时会执行
reject(false),但组件调用时只写了then回调,没有添加catch回调处理失败情况,一旦请求出错就会抛出未捕获的Promise异常。 - 已卸载组件更新状态:如果异步请求完成前,当前组件已经被卸载(比如用户提前退出页面、路由跳转),此时在
then回调中调用setStep会触发已卸载组件的状态更新,React会抛出对应的更新错误。 - 你当前的thunk中
finally逻辑为空,请求结束后没有关闭加载状态,可能触发SpinnerButton组件的状态异常,和组件状态更新同时触发时会导致渲染冲突。 - switch分支没有default兜底逻辑,如果type不匹配会导致url为空、data为null,直接触发请求失败。
解决方法
- 给Promise调用添加catch回调处理错误情况,同时添加组件挂载状态判断,避免卸载后更新状态:
// 组件内新增挂载标记 const isMounted = useRef(true); useEffect(() => { return () => { isMounted.current = false; }; }, []); const onPressBuyCharge = () => { dispatch( otherServices({ type: SimCard_Charge, payload: { phoneNumber: phoneNumber, amount: amount, ewallets: selectedServicesWalletOptions, }, }) ).then(res => { if (isMounted.current) { setStep('input'); } }).catch(err => { if (isMounted.current) { // 这里可以添加请求失败的提示逻辑,比如弹出toast console.log('请求失败', err); } }); };
- 补全thunk中的finally逻辑,关闭加载状态:
// 在otherServices的Promise中修改finally逻辑 .finally(() => { dispatch(toggleButtonSpinner(false)); });
- 给switch添加default分支,避免未知type导致请求参数异常:
switch (type) { // 原有case逻辑 default: return Promise.reject('未知的服务类型'); }
可选优化
你当前使用的InputNumber组件用的是defaultPhone属性,属于非受控组件,当切回input步骤时如果phoneNumber被清空,可能不会更新输入框显示,建议改成受控组件:
<InputNumber value={phoneNumber} onChangeText={e => onChangePhone(e)} onPressSimCard={onPressSimCard} onPressContacts={onPressSelectContacts} />
内容的提问来源于stack exchange,提问作者Mohamadamin
相关产品推荐
相关产品推荐

