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
相关产品推荐
相关产品推荐

