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

React Router动态路由URL新标签页打开报错该如何解决?

问题根因

你对报错原因的判断是正确的,React Router 中的 location.state 存储在当前浏览器会话的历史栈中,仅通过同站点内的 Link 组件跳转时才会携带该数据。直接刷新页面、新开标签页访问URL、手动输入URL的场景下,历史栈中没有对应状态数据,就会出现取值报错。这不是动态路由的固有缺陷,是数据传递方式选择不当导致的问题。

解决方案

1. 统一路由参数规则

你当前路由定义的路径为 /movie/:id,但跳转时实际拼接的是电影标题,首先修正跳转逻辑,用全局唯一的电影ID作为路由参数,避免标题重复、特殊字符转义的问题:

// Result组件内Link部分修正后的代码
<Link
  to={{
    pathname: `/movie/${props.id}`,
    state: { ...props },
  }}
>

2. 改造ResultPage的取值逻辑,添加数据兜底

不再完全依赖location.state取数,做两层兼容:

  • 从同页面跳转过来有location.state时,直接用该数据渲染,无需额外发请求,保证跳转体验
  • 无location.state时,从URL路由参数中取出电影ID,调用单电影详情接口拉取数据后再渲染

以下是React Router v5版本的ResultPage示例代码:

import { useEffect, useState } from 'react';

export default function ResultPage(props) {
  const [movieData, setMovieData] = useState(props.location.state);
  const [loading, setLoading] = useState(!props.location.state);
  // 从路由参数中拿到电影ID
  const movieId = props.match.params.id;

  useEffect(() => {
    // 没有state数据时调用接口拉取电影详情
    if (!props.location.state) {
      // 此处替换为你实际使用的单电影查询接口
      fetch(`https://api.themoviedb.org/3/movie/${movieId}?api_key=你的API_KEY`)
        .then(res => res.json())
        .then(data => {
          setMovieData(data);
          setLoading(false);
        })
        .catch(err => {
          // 可添加异常处理,比如跳转到404页、提示电影不存在
          setLoading(false);
        })
    }
  }, [movieId, props.location.state])

  if (loading) return <div>加载中...</div>
  if (!movieData) return <div>未查询到对应电影信息</div>

  // 此处为你原来的页面渲染逻辑,直接使用movieData即可
  return (
    <div>
      <h1>{movieData.title}</h1>
      {/* 剩余渲染内容 */}
    </div>
  )
}

可选优化

如果想要进一步提升体验,可以在搜索结果页缓存已经拉取过的电影数据,新开页面访问时优先从缓存取数,减少重复接口请求。

内容的提问来源于stack exchange,提问作者cdt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 16:42:03