React中使用useNavigate传递组件数据时出现undefined错误求助
React应用数据传递异常排查方案
一、流派点击后子组件数据undefined问题
1. 检查useNavigate的state传递格式
React Router的useNavigate必须通过配置对象的state字段传递数据,错误写法会直接导致数据丢失:
// 错误写法 navigate('/results', artists); // 正确写法 navigate('/results', { state: { artists, playlists, tracks } });
2. Results组件接收state需做兜底处理
用useLocation获取state时,必须处理state为空的情况,避免解构undefined触发报错:
import { useLocation } from 'react-router-dom'; const Results = () => { const location = useLocation(); // 给每个字段设置默认空数组,防止解构失败 const { artists = [], playlists = [], tracks = [] } = location.state || {}; return ( <> <ArtistList artists={artists} /> <PlaylistList playlists={playlists} /> <TrackList tracks={tracks} /> </> ); };
3. Promise.all的异步请求需完整处理
确保所有请求都解析为JSON格式,同时捕获异常避免空数据传递:
const handleGenreClick = async (genre) => { try { // 发起三个并行请求 const [artistRes, playlistRes, trackRes] = await Promise.all([ fetch(`/api/spotify/artists?genre=${genre}`), fetch(`/api/spotify/playlists?genre=${genre}`), fetch(`/api/spotify/tracks?genre=${genre}`) ]); // 必须解析响应为JSON,否则拿到的是Response对象而非业务数据 const artists = await artistRes.json(); const playlists = await playlistRes.json(); const tracks = await trackRes.json(); // 确认数据存在再执行跳转 if (artists && playlists && tracks) { navigate('/results', { state: { artists, playlists, tracks } }); } } catch (err) { console.error('请求Spotify数据失败:', err); // 可添加用户可见的错误提示 } };
4. 子组件接收props需做防御性处理
子组件中直接使用props前,用可选链或默认值避免undefined报错:
// ArtistList组件示例 const ArtistList = ({ artists = [] }) => { return ( <div className="artist-list"> {/* 用可选链?.防止artists为undefined时map报错 */} {artists?.map(artist => ( <div key={artist.id} onClick={() => handleArtistClick(artist)}> {artist.name} </div> ))} </div> ); };
二、艺术家点击路由与数据传递问题
1. 配置正确的动态路由
在路由规则中定义带参数的路由:
// 路由配置文件 import { Routes, Route } from 'react-router-dom'; import TopTracks from './TopTracks'; function AppRoutes() { return ( <Routes> {/* 其他路由 */} <Route path="/:artistName" element={<TopTracks />} /> </Routes> ); }
2. 点击艺术家时的请求与跳转逻辑
确保请求成功后,通过state传递数据到TopTracks组件:
const handleArtistClick = async (artist) => { try { const res = await fetch(`/api/spotify/top-tracks?artistId=${artist.id}`); const topTracks = await res.json(); navigate(`/${artist.name}`, { state: { topTracks } }); } catch (err) { console.error('获取艺术家热门曲目失败:', err); } };
3. TopTracks组件接收数据与路由参数
用useLocation拿state,useParams拿艺术家名称,同时做兜底处理:
import { useLocation, useParams } from 'react-router-dom'; const TopTracks = () => { const { artistName } = useParams(); const location = useLocation(); const { topTracks = [] } = location.state || {}; return ( <div className="top-tracks"> <h2>{artistName}的热门曲目</h2> {topTracks.map(track => ( <div key={track.id}>{track.name}</div> ))} </div> ); };
三、额外排查建议
- 在
Promise.all之后、navigate之前打印数据,确认请求返回的是预期格式 - 在Results、TopTracks组件中打印
location.state,查看数据是否成功传递 - 如果用户直接刷新页面,
location.state会丢失,这种场景需要从URL参数重新请求数据,或用localStorage临时存储数据
内容的提问来源于stack exchange,提问作者Scottsdaaale
相关产品推荐
相关产品推荐

