React中基于useMutation实现依赖API异步调用及状态更新问题
问题:API调用顺序导致状态未更新的修复方案
问题场景
需要按顺序调用两个API:getOperator和getPlans,其中getPlans必须在getOperator返回数据后执行。getOperator接收手机号作为输入,返回如下格式的运营商与地区信息:
{ "operator": "AT&T", "circle": "Washington" }
当手机号长度等于10时触发API调用,目前getOperator能正常获取数据,但调用getPlans时,circleName和operatorName状态未更新,仍使用旧值,导致getPlans参数错误。
问题原因
- React状态更新是异步的:调用
mutateOperator后,setOperatorName和setCircleName不会立即更新状态值。 mutateOperator本身是异步操作:onSubmit函数中调用mutateOperator后立刻执行mutatePlan,此时getOperator的请求还未完成,状态值仍为旧数据。
修复方案
核心思路
将getPlans的调用逻辑移到getOperator请求成功的回调中,确保使用最新的返回数据作为参数,而非依赖尚未更新的状态。
修改后的代码
- 更新
mutateOperator的配置,在onSuccess中调用mutatePlan:
const { mutate: mutateOperator } = useMutation(getOperatorDetails, { onSuccess: (data) => { setOperator(data); setOperatorName(data?.operator); setCircleName(data?.circle); console.log('operator plans', data); // 使用getOperator返回的最新数据构造getPlans的参数 const planParams = { operator: data?.operator, circle: data?.circle }; mutatePlan(planParams); }, onError: (error: any) => { alert(error?.msg); }, });
- 简化
onSubmit函数,移除提前调用的mutatePlan:
const onSubmit = async (value: any) => { const opr = { mobile_no: value, }; mutateOperator(opr); };
- 优化其他冗余代码:
- 删除
callApi中重复的setPhoneNumber(value),handleOnChange已完成手机号状态设置; - 删除
getRechargePlans中的setPlans(plans),useMutation的onSuccess回调已处理状态更新; - 移除Input组件中重复的
{(e:any)=>setPhoneNumber(e.target.value)},避免重复设置状态:
<Input label='Phone number' variant='' type='text' className='rounded-lg' pattern="[0-9]*" inputMode="numeric" onChange={(e)=>handleOnChange(e)} maxLength={10} />
额外优化建议
- 在调用
mutateOperator前设置loading为true,统一管理加载状态; - 给
useState设置更合理的初始值,比如phoneNumber初始值设为空字符串而非0,避免类型转换问题:
const [phoneNumber, setPhoneNumber] = useState<string>('');
内容的提问来源于stack exchange,提问作者alex divine
相关产品推荐
相关产品推荐

