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

React调用State setter后状态仍为undefined的问题咨询

问题原因与解决方案

你的问题核心是React的useState状态更新是异步的,调用setAccessToken和setRefreshToken后,状态不会立刻更新,所以在同一个handleClickButton函数里,后续的console.log(accessToken)和getPlaylists(accessToken)用的还是更新前的旧值(初始是空字符串,第一次点击时就是"",你看到的undefined大概率是误判,但本质是异步更新的逻辑问题)。

具体解决方法

方法1:直接使用接口返回的token值(当前场景推荐)

既然你已经从getToken/tokenRefresh拿到了最新的token对象,里面包含有效accessToken和refreshToken,调用状态更新函数后,直接用这个对象里的值去调用getPlaylists,不用等状态变量更新:

修改后的handleClickButton代码:

const handleClickButton = async () => {
    let currentAccessToken = accessToken;
    let currentRefreshToken = refreshToken;

    if(!accessToken && !refreshToken) {
        const token = await getToken(code)
        currentAccessToken = token.accessToken;
        currentRefreshToken = token.refreshToken;
        setAccessToken(currentAccessToken)
        setRefreshToken(currentRefreshToken)
        console.log("if", currentAccessToken, currentRefreshToken)
    }
    else {
        const token = await tokenRefresh(refreshToken)
        currentAccessToken = token.accessToken;
        currentRefreshToken = token.refreshToken;
        setAccessToken(currentAccessToken)
        setRefreshToken(currentRefreshToken)
        console.log("else", currentAccessToken, currentRefreshToken)
    }

    // 直接用最新拿到的token值调用接口
    const retrievedPlaylists = await getPlaylists(currentAccessToken)
    console.log("retrievedPlaylists",retrievedPlaylists)
    setPlaylists(retrievedPlaylists)
}

方法2:用useEffect监听状态变化

如果后续逻辑必须依赖更新后的状态变量,可以添加useEffect监听accessToken,当它变化时自动执行接口调用:

首先修改handleClickButton只负责更新token:

const handleClickButton = async () => {
    if(!accessToken && !refreshToken) {
        const token = await getToken(code)
        setAccessToken(token.accessToken)
        setRefreshToken(token.refreshToken)
    }
    else {
        const token = await tokenRefresh(refreshToken)
        setAccessToken(token.accessToken)
        setRefreshToken(token.refreshToken)
    }
}

然后添加useEffect监听状态变化:

useEffect(() => {
    // 只有当accessToken不为空时才调用接口
    if(accessToken) {
        const fetchPlaylists = async () => {
            const retrievedPlaylists = await getPlaylists(accessToken)
            console.log("retrievedPlaylists",retrievedPlaylists)
            setPlaylists(retrievedPlaylists)
        }
        fetchPlaylists()
    }
}, [accessToken]) // 依赖accessToken,当它变化时执行

补充说明

React的状态更新是批量异步的,目的是提升性能,所以不要在调用状态更新函数后,立刻期望状态变量变成新值。如果需要在更新后立刻使用新值,优先使用接口返回的原始数据;如果必须依赖状态,就用useEffect监听变化触发逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:35:22