React.js开发Spotify克隆:仅渲染最后一个播放列表问题
问题:Spotify克隆项目中播放列表仅渲染最后一项
我使用React.js结合Spotify Web API、axios开发Spotify克隆项目,同时运用Context API与styled-components。在Playlists.jsx中获取当前用户播放列表,接口可成功获取数据,但页面仅渲染最后一个播放列表。
相关代码
index.js
const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <StateProvider initialState={initialState} reducer={reducer} > <App /> </StateProvider> </React.StrictMode> );
StateProvider.jsx
import {createContext,useContext,useReducer} from "react"; export const StateContext=createContext(); export const StateProvider=({children,initialState,reducer})=>( <StateContext.Provider value={useReducer(reducer,initialState)}> {children} </StateContext.Provider> ) export const useStateProvider=()=>useContext(StateContext);
spotify.js(函数片段)
const[{token},dispatch]=useStateProvider(); useEffect(()=>{ const getUserInfo=async()=>{ const {data}=await axios.get("https://api.spotify.com/v1/me",{ headers:{ Authorization:"Bearer "+token, "Content-Type": "application/json", }, }) const userInfo={ userId:data.id, userName:data.display_name, } dispatch({type:reducerCases.SET_USER,userInfo}) } getUserInfo(); },[token,dispatch])
Playlists.jsx
function Playlists() { const [{token,playlists},dispatch] = useStateProvider(); useEffect(()=>{ const playListData=async()=>{ const response=await axios.get( " https://api.spotify.com/v1/me/playlists ", { headers:{ Authorization:"Bearer "+token, "Content-Type": "application/json", }, } ) const {items}=response.data; console.log(response,"heelo") const playlists=items.map(({name,id})=> { return{name,id} }) dispatch({type:reducerCases.SET_PLAYLISTS,playlists}) } playListData() },[token,dispatch]) return ( <Container> <ul> {playlists.map(({name,id})=>{ return( <li key={id}>{name}</li> ) })} </ul> </Container> ) }
解决方法
问题核心在于reducer中处理SET_PLAYLISTS的逻辑错误,导致state里的playlists被错误处理成单个对象而非完整数组。
- 修正reducer的
SET_PLAYLISTS分支,确保直接赋值完整数组:
case reducerCases.SET_PLAYLISTS: return { ...state, playlists: action.playlists // 直接将传入的数组赋值给state.playlists };
避免以下错误写法:
- 只取数组最后一项(比如
playlists: action.playlists[action.playlists.length - 1]) - 循环遍历中覆盖数组为单个元素(如
forEach里直接把playlists设为当前item)
- 验证state中
playlists的类型:在Playlists组件中添加打印,确认playlists是数组而非单个对象:
console.log('当前playlists状态:', playlists);
- 确认initialState中
playlists初始值为数组:
const initialState = { // 其他状态... playlists: [] // 初始化为空数组 };
内容的提问来源于stack exchange,提问作者Rajneesh Sajwan
相关产品推荐
相关产品推荐

