useEffect获取AsyncStorage后调用fetch时userId状态未设置的问题
问题描述
我在React Native项目中使用AsyncStorage存储用户ID,登录时通过以下代码保存:
const storeUserId = async (id) => { try { await AsyncStorage.setItem( 'userId', id, ); } catch (error) { console.log(error); } } // 调用方式 storeUserId(userGuid); navigation.navigate("Home");
跳转到Home页面后,在useEffect中读取userId并更新state:
const [userId, setUserId] = useState(''); import AsyncStorage from '@react-native-async-storage/async-storage'; useEffect(() => { AsyncStorage.getItem('userId').then(value => { if (value != null) { setUserId(value.toString()); console.log("u " + value); // 控制台输出正确的userId:u 52ba85d7-5d16-4012-940d-94cddda978b2 getData(0); } }); }, []);
但调用getData(0)时,控制台输出的userId为空:
const getData = async (id) => { console.log("2 " + userId); // 输出空字符串 setOnRefresh(true); fetch('https://soppinga.com/api/Home/GetPolls?id=' + id + "&userId=" + userId, { method: 'GET', headers: { 'Content-Type': 'application/json' }}) .then(function(response){ return response.json(); }) .then(function(json){ heartRef2.current = true; heartRef.current = true; loadData(json); setOnRefresh(false); }) .catch(function(error) { console.log('There has been a problem with your fetch operation: ' + error.message); throw error; }); }
导致fetch请求因userId为空无法正常完成,请问如何及时获取userId并传入fetch请求?
解决方案
方法1:直接传递读取到的userId值
setUserId是异步操作,调用后state不会立即更新,因此可以直接将从AsyncStorage读取到的value作为参数传给getData,跳过state更新的等待:
useEffect(() => { AsyncStorage.getItem('userId').then(value => { if (value != null) { const userIdValue = value.toString(); setUserId(userIdValue); console.log("u " + userIdValue); getData(0, userIdValue); // 直接传入读取到的userId } }); }, []); // 修改getData函数,新增userId参数 const getData = async (id, userId) => { console.log("2 " + userId); // 此时能拿到正确的userId setOnRefresh(true); // 使用模板字符串拼接URL更清晰 fetch(`https://soppinga.com/api/Home/GetPolls?id=${id}&userId=${userId}`, { method: 'GET', headers: { 'Content-Type': 'application/json' }}) .then(response => response.json()) .then(json => { heartRef2.current = true; heartRef.current = true; loadData(json); setOnRefresh(false); }) .catch(error => { console.log('There has been a problem with your fetch operation: ' + error.message); throw error; }); }
方法2:监听userId state的变化
如果业务逻辑必须依赖state中的userId,可以新增一个监听userId的useEffect,当userId更新后再触发getData:
useEffect(() => { AsyncStorage.getItem('userId').then(value => { if (value != null) { setUserId(value.toString()); console.log("u " + value); } }); }, []); // 新增useEffect,仅当userId变化时执行 useEffect(() => { if (userId) { // 确保userId不为空时才调用 getData(0); } }, [userId]); // 依赖数组添加userId,触发条件为userId更新
方法3:用async/await优化异步逻辑可读性
将useEffect中的异步操作改为async/await写法,代码逻辑更直观:
useEffect(() => { const initData = async () => { try { const value = await AsyncStorage.getItem('userId'); if (value != null) { const userIdValue = value.toString(); setUserId(userIdValue); console.log("u " + userIdValue); getData(0, userIdValue); } } catch (error) { console.error('读取userId失败:', error); } }; initData(); }, []);
内容的提问来源于stack exchange,提问作者redoc01
相关产品推荐
相关产品推荐

