React Context首次渲染无法传递userData问题求助
问题原因
React的setState是异步操作,调用setUserData(data)后,当前作用域内的userData并不会立刻更新为新值,仍然是初始的空数组。所以你紧接着调用fetchToken时传入的userData还是旧的初始值,这就是首次渲染拿不到数据的原因。而热重载后组件重新渲染,userData已经完成更新,自然能拿到正确值。
解决办法
方案1:直接使用接口返回的data传递给fetchToken
既然在接口回调里已经拿到了最新的用户数据data,直接把它传给fetchToken即可,无需等待状态更新:
useEffect(() => { if (isAuth) apiClient .get("api/v1/user/params") .then(({ data }) => { setUserData(data); setUserLoading(false); // 直接用接口返回的data,而非userData状态 fetchToken({ setTokenFound, userData: data, userLoading: false, }); }) }, [isAuth]); // 务必添加依赖项
方案2:通过监听userData状态变化触发fetchToken
新增一个useEffect,监听userData和userLoading的变化,确保只有当用户数据加载完成且存在时,才调用fetchToken:
const [userData, setUserData] = useState<any>([]); const [isTokenFound, setTokenFound] = useState<boolean>(false); const [userLoading, setUserLoading] = useState<any>(true); // 获取用户数据的原有逻辑 useEffect(() => { if (isAuth) apiClient .get("api/v1/user/params") .then(({ data }) => { setUserData(data); setUserLoading(false); }) }, [isAuth]); // 监听状态变化,触发token获取 useEffect(() => { // 确保数据已加载完成且存在有效数据 if (!userLoading && userData?.data) { fetchToken({ setTokenFound, userData, userLoading, }); } }, [userData, userLoading, setTokenFound]); // 添加必要依赖
方案3:优化fetchToken参数,脱离状态依赖
修改fetchToken,让它直接接收用户数据作为独立参数,避免依赖Context状态:
// 重新定义fetchToken参数类型 type FetchTokenProps = { setTokenFound: React.Dispatch<React.SetStateAction<boolean>>; userData: any; }; export const fetchToken = ({ setTokenFound, userData }: FetchTokenProps) => { return getToken(messaging, { vapidKey: 'fake' }).then((currentToken) => { // 原有逻辑不变 }); }; // Context中调用时直接传入接口返回的data fetchToken({ setTokenFound, userData: data, });
关于localStorage无效的说明
你之前尝试用localStorage无效,大概率是因为调用setUserData后立刻存的是当时的旧userData,而非接口返回的data。如果要通过localStorage实现,应该在接口回调里直接把data存入localStorage,然后在fetchToken里读取localStorage的内容,而不是依赖状态值。
内容的提问来源于stack exchange,提问作者KomarCorporation
相关产品推荐
相关产品推荐

