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

