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

React中使用useLazyQuery后signType12状态重置为初始值的问题

问题:设置signType12后,useLazyQuery的onCompleted回调中该值变回初始null

点击按钮将signType12设置为url或email后,useEffect会触发调用useLazyQuery对应的API,但在useLazyQuery的onCompleted回调中,signType12却变成了初始值null。

相关代码

业务逻辑代码

const [getOrder] = useLazyQuery(GET_BUSINESS_LIFE_ORDER, {
  fetchPolicy: "no-cache",
  onError: useCallback((err: any) => {
    apiErrorHandler(err);
    setIsTransLoading(false);
  }, []),
  onCompleted: useCallback(({ getBusinessLifeOrder }: any) => {
    setLifeOrder(getBusinessLifeOrder);
    setLoading(false);
    console.log(signType12, "sign12");
    if (getBusinessLifeOrder.signatureId) {
      getOrderSignatureInfo({
        variables: {
          id: orderId,
        },
      });
    } else if (signType12 != null) {
      companySignDoc({
        variables: {
          orderId: orderId,
          deliveryMethod:
            signType12 == "url" ? "URL" : signType12 == "email" ? "EMAIL" : null,
          userType: "LEGALREPRESENTATIVE",
          signer1: {
            name: getBusinessLifeOrder.contactInfo.name,
            email: getBusinessLifeOrder.contactInfo.email,
          },
        },
      });
    }
    // setIsTransLoading(false);
  }, []), 
});

useEffect(() => {
  if (signType12) {
    console.log(signType12, "sign12");
    // setIsTransLoading(true);
    getOrder({ variables: { id: orderId } });
  }
}, [signType12]);

按钮交互代码

<button
  onClick={() => {
    setSignType12('url')
  }}>
  Assinar agora
</button>
<button
  onClick={() => {
    setSignType12('email')
  }}>
  Enviar documento por email
</button>

问题原因

这是闭包导致的 stale 值问题:onCompleted回调通过useCallback包裹,但依赖项数组是空的,所以它捕获的是组件初始化时signType12的初始值(null)。即使后续signType12被更新,回调里依然只能访问到最初捕获的那个值。

解决方案

方案1:更新useCallback的依赖项

把signType12和orderId(如果orderId也会动态变化)加入useCallback的依赖数组,确保回调能获取到最新的变量值:

onCompleted: useCallback(({ getBusinessLifeOrder }: any) => {
  // 原有逻辑保持不变
}, [signType12, orderId]), 

方案2:调用getOrder时传递signType12

如果不想依赖外部变量的更新,也可以在调用getOrder时把signType12作为自定义上下文参数传递,在onCompleted中直接从上下文获取:

// 在useEffect中调用getOrder时传递参数
useEffect(() => {
  if (signType12) {
    getOrder({ 
      variables: { id: orderId },
      context: { currentSignType: signType12 }
    });
  }
}, [signType12]);

// 在onCompleted中获取传递的参数
onCompleted: useCallback(({ getBusinessLifeOrder }: any, { context }) => {
  const signType12 = context.currentSignType;
  // 后续逻辑使用获取到的signType12即可
}, []), 

注意事项

  • 方案1中,依赖项更新后,React会在signType12或orderId变化时重新创建onCompleted回调,确保能拿到最新值。
  • 方案2需要确认你的GraphQL客户端支持通过context传递自定义参数(Apollo Client原生支持该特性)。

内容的提问来源于stack exchange,提问作者Rahul Kumar Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:30:54