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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:02:42