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

React useState未即时更新导致Screen3无法正确渲染问题

问题分析

核心问题是**screenType的赋值时机与props.products的异步更新不同步**:

  • 在handleEligibleProducts中调用props.employeeProduct(data)后,Redux更新products状态是异步操作,此时props.products还未变为目标数组,isActive依然保持初始的false。
  • 紧接着直接根据!isActive设置screenType=2,后续当props.products更新触发useEffect将isActive改为true时,没有重新触发screenType的判断逻辑,导致页面始终停留在Screen2,无法切换到Screen3。
解决方案

把screenType的判断逻辑从handleEligibleProducts末尾移到一个**依赖props.products、isActive、statusCode、productList、allEligibilityFlagZero**的useEffect中,确保关键状态变化时,自动重新计算并切换对应屏幕。同时需要将接口返回的关键变量转为组件状态,让它们能被useEffect监听。

修改后的关键代码片段
function LandingPage(props) {
  const [eligibleProducts, setEligibleProducts] = useState([]);
  const [screenType, setScreenType] = useState();
  const [url, setUrl] = useState("");
  const [message, setMessage] = useState("");
  const [loading, setLoading] = useState(false);
  const [isActive, setisActive] = useState(false);
  // 新增状态存储接口返回的关键变量
  const [statusCode, setStatusCode] = useState(null);
  const [productList, setProductList] = useState(null);
  const [allEligibilityFlagZero, setAllEligibilityFlagZero] = useState(false);

  const { pocBusinessEmail, pocBusinessName } = props;

  useEffect(() => {
    handleEligibleProducts();
  }, []);

  useEffect(() => {
    if(props.products && props.products.filter(product => product.productStatus === 2).length > 0){
      setisActive(true);
    } else {
      // 补充重置逻辑,避免状态不一致
      setisActive(false);
    }
  }, [props.products]);

  // 新增useEffect专门处理屏幕切换逻辑
  useEffect(() => {
    if (!statusCode) return; // 未获取接口数据时不执行

    if (statusCode !== 200) {
      setScreenType(4);
    } else if (!(productList && productList.length !== 0) || allEligibilityFlagZero) {
      setScreenType(1);
    } else if (!isActive) {
      setScreenType(2);
    } else {
      setScreenType(3);
    }
  }, [statusCode, productList, allEligibilityFlagZero, isActive]);

  const handleEligibleProducts = async () => {
    setLoading(true);
    let data = {
      userType: 102,
      email: window.localStorage.getItem("email")
    };

    try {
      const res = await props.getEligibleProducts(data);
      const { statusCode: resStatusCode, msgText, productList: resProductList, Url } = res.data.responsePayload;
      
      // 将接口返回的关键数据存入组件状态
      setStatusCode(resStatusCode);
      setProductList(resProductList);
      
      if (Url) {
        setUrl(new URL(Url));
      }

      if (resStatusCode === 200) {
        await props.employeeProduct({
          employeeId: props.employeeId,
          products: null
        });
      } 

      if (resProductList) {
        setEligibleProducts(resProductList.map(product => ({ ...product, selected: false })));
        const flagZero = resProductList.length && resProductList.every(product => product.eligibilityFlag === 0);
        setAllEligibilityFlagZero(flagZero);
      }

      if (resStatusCode !== 200) {
        setMessage(msgText);
      }
      
      setLoading(false);
    } catch (error) {
      setLoading(false);
      console.log("big error: " + error);
    }
  };

  // 其余原有代码保持不变...
}
核心改动说明
  1. 将接口返回的statusCode、productList、allEligibilityFlagZero转为组件状态,确保它们能被useEffect监听。
  2. 新增专属useEffect,当statusCode、productList、allEligibilityFlagZero、isActive任一状态变化时,自动重新计算screenType。这样当props.products更新触发isActive变为true时,会自动切换到Screen3。
  3. 补充isActive的重置逻辑,避免特殊场景下的状态不一致问题。

内容的提问来源于stack exchange,提问作者Angela Rubchinksy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:25:35