登录后Spotify API数据无法自动渲染,需刷新页面问题求助
问题根源
- token读取时机滞后:
SpotifyApiState组件挂载时仅一次性读取localStorage的token,登录后token存入localStorage但组件不会自动重新读取,导致getCategories调用时使用的是旧的空token。 - getCategories依赖静态token:
getCategories函数依赖组件初始化时的accessToken变量,而非实时从localStorage获取最新值,登录后首次调用仍用空token请求。 - 初始状态不匹配:
categorydata初始值为数组[],但接口返回的是包含categories属性的对象,导致渲染判断逻辑异常。
修复步骤
1. 修改SpotifyApiState.js,实时获取token并修正初始状态
import SpotifyApiContext from './SpotifyApiContext' import axios from "axios"; import { useState, useCallback } from 'react'; const SpotifyApiState = (props) => { // 修正初始状态为null,匹配接口返回的对象结构 const [categorydata, setCategorydata] = useState(null); // 用useCallback稳定函数引用,避免子组件useEffect重复触发 const getCategories = useCallback(async () => { // 每次调用时实时从localStorage获取最新token const accessToken = localStorage.getItem('token'); if (!accessToken) { console.error('Access token not available yet.'); return; } const options = { method: 'GET', url: `https://api.spotify.com/v1/browse/categories`, params: { country: 'IN', offset: '0', limit: '10', }, headers: { 'Authorization': 'Bearer ' + accessToken } }; try { const response = await axios.request(options); console.log('Fetch categories data', response.data); setCategorydata(response.data); } catch (error) { console.error('Error Fetching categories data', error); } }, []); return ( <SpotifyApiContext.Provider value={{ categorydata, getCategories }}> {props.children} </SpotifyApiContext.Provider> ) } export default SpotifyApiState
2. 优化MainRightSection的渲染判断与依赖项
const MainRightSection = (props) => { const context = useContext(SpotifyApiContext); const { categorydata, getCategories } = context; useEffect(() => { getCategories(); getAllPlaylists(); }, [getCategories]); // 添加getCategories到依赖项,确保函数更新时重新触发 const getplaylistID = (id) => { console.log(id); getPlaylists(id); } // 优化数据存在性判断,更严谨 const hasValidData = categorydata?.categories?.items?.length > 0; return ( <div className='relative z-0'> <div className='px-4 flex flex-row flex-wrap gap-6'> <section className='mb-4 w-full'> <div className='pt-6'> <Swiper slidesPerView={2} spaceBetween={10} breakpoints={breakpoints}> {!hasValidData ? ( <div className='text-center text-2xl'> No Data to display yet ... </div> ) : ( categorydata.categories.items.map((items, index) => ( <SwiperSlide key={index}> <CategoryCard icon={items.icons} item={items} /> </SwiperSlide> )) )} </Swiper> </div> </section> </div> </div> ) } export default MainRightSection
修复原理
- 实时获取token:每次调用
getCategories时从localStorage读取最新token,确保登录后能拿到有效凭证。 - 稳定函数引用:用
useCallback包裹getCategories,避免子组件useEffect因函数引用变化重复触发,同时保证依赖项合规。 - 严谨状态判断:修正初始状态并优化数据存在性判断,避免因类型不匹配导致的渲染错误。
内容的提问来源于stack exchange,提问作者Prashant Rao
相关产品推荐
相关产品推荐

