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

React中如何检查State值后执行函数?解决异步加密跳转问题

问题描述

我需要把一些值存入Cookie,但存入前得先加密。现在所有初始State都是undefined,跳转下一页时Cookie存的是undefined,导致获取Cookie时异常。怎么确保所有State都赋值完成后再跳转?不知道该在哪用Promise和async/await。

解决方案

核心思路是等所有加密请求和State更新完成后,再执行Cookie存储和页面跳转,具体实现如下:

1. 用Promise.all批量处理加密请求

原来的代码里每个加密请求单独用then处理,无法保证所有加密操作同步完成。把所有加密请求打包成Promise数组,通过Promise.all等待全部完成后,再一次性更新State。

2. 改用async/await优化异步逻辑

将axios请求和加密流程统一改成async/await写法,替代嵌套的then/catch,让逻辑更连贯,也更容易控制执行顺序。

3. 直接在流程末尾执行跳转

不再依赖监听State变化触发跳转,而是在所有数据处理、State更新完成后,直接调用Cookie存储和页面跳转逻辑,彻底避免State未就绪的问题。

修改后的完整代码

LoadingPage组件

import { useState, useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import axios from 'axios';
import { encryption } from './你的加密文件路径';
import { setCookieApp } from './你的Cookie工具路径';
import Loading from './你的Loading组件路径';

export default function LoadingPage() {
  const location = useLocation();
  const navigate = useNavigate();
  const [token, setToken] = useState();
  const [refreshToken, setRefreshToken] = useState();
  const [creationDate, setCreationDate] = useState();
  const [lifeTime, setLifeTime] = useState();
  const [mobile, setMobile] = useState();
  const [nationalCode, setNationalCode] = useState();
  const [userId, setUserId] = useState();
  const [companyId, setCompanyId] = useState();
  const [name, setName] = useState();

  useEffect(() => {
    const fetchAndProcessData = async () => {
      try {
        const data = {};
        const tokenId = '你的tokenId生成逻辑'; // 补全你的tokenId代码

        // 1. 获取原始接口数据
        const response = await axios.post('https://你的接口地址', data, {
          headers: {
            Authorization: `Basic ${tokenId}`,
          },
        });

        // 2. 批量执行所有加密请求,等待全部完成
        const [encryptedCreationDate, encryptedLifeTime, encryptedMobile, encryptedNationalCode, encryptedUserId, encryptedCompanyId, encryptedName] = await Promise.all([
          encryption(response.data.result.creationDate),
          encryption(response.data.result.lifeTime),
          encryption(response.headers.mobile),
          encryption(response.headers.nationalcode),
          encryption(response.headers.userid),
          encryption(response.headers.companyid),
          encryption(response.headers.name),
        ]);

        // 3. 一次性更新所有State
        setToken(response.data.result.value);
        setRefreshToken(response.data.result.refreshToken);
        setCreationDate(encryptedCreationDate);
        setLifeTime(encryptedLifeTime);
        setMobile(encryptedMobile);
        setNationalCode(encryptedNationalCode);
        setUserId(encryptedUserId);
        setCompanyId(encryptedCompanyId);
        setName(encryptedName);

        // 4. 所有数据就绪后,存储Cookie并跳转
        const dataArray = [
          response.data.result.value,
          response.data.result.refreshToken,
          encryptedCreationDate,
          encryptedLifeTime,
          encryptedMobile,
          encryptedNationalCode,
          encryptedUserId,
          encryptedCompanyId,
          encryptedName,
        ];
        setCookieApp(dataArray);
        navigate("../dashboard");
      } catch (error) {
        console.error('请求或加密失败:', error);
        // 可添加错误处理逻辑,比如跳转到错误页面
      }
    };

    fetchAndProcessData();
  }, []);

  return (
    <div>
      <Loading />
    </div>
  );
}

加密函数(保持原有逻辑即可)

export const encryption = async (value) => {
  const response = await axios.post(
    "https://你的加密接口地址",
    JSON.stringify({
      value: value,
    }),
  ); 
  return response.data.result.value;
};

关键改动说明

  • Promise.all确保加密全完成:7个加密请求并行执行,全部完成后才会继续后续操作,避免部分State未更新。
  • async/await简化异步流程:替代嵌套的then链,代码可读性更强,执行顺序更清晰。
  • 直接在流程末尾跳转:彻底摆脱对State变化的依赖,从根源解决State未就绪就跳转的问题。
  • 统一错误捕获:把接口请求和加密请求的错误集中处理,方便排查问题。

内容的提问来源于stack exchange,提问作者Faeze Gholami

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 02:27:45