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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 00:52:29