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

React中Link组件传递state至新页面后props.location.state为undefined的问题

问题原因分析

你遇到的这个问题其实是React Router的一个常见限制:当你使用<Link target="_blank">打开新标签页/窗口时,state参数是存储在原窗口的浏览器内存history栈中的,而新窗口属于完全独立的浏览器上下文,无法访问原窗口的history数据,所以新页面的props.location.state自然就变成了undefined。

state属性本来就是为同窗口内的路由跳转设计的,跨窗口场景下并不适用。

可行解决方案

方案1:去掉target="_blank"(最简,但不符合新窗口需求时跳过)

如果业务允许在当前窗口跳转,直接移除target="_blank"属性,state就能正常传递:

// Component 1
<Link 
  to={{pathname:"/somepath/xyz", state:{content:"<div>....</div>"}}} 
  rel="noopener noreferrer" 
  className="..." 
/>

Component 2里就能正常通过props.location.state.content拿到HTML内容了。

方案2:通过URL查询参数传递(适合短HTML内容)

把HTML字符串编码后作为URL的查询参数传递,缺点是URL有长度限制,且要注意XSS风险:

// Component 1
import { Link } from 'react-router-dom';

const htmlContent = "<div>....</div>";
// 对HTML字符串进行URI编码,避免特殊字符破坏URL结构
const encodedContent = encodeURIComponent(htmlContent);

<Link 
  to={`/somepath/xyz?content=${encodedContent}`} 
  target="_blank" 
  rel="noopener noreferrer" 
  className="..." 
/>
// Component 2
import { useEffect, useState } from 'react';

function Component2(props) {
  const [content, setContent] = useState('');

  useEffect(() => {
    // 解析URL查询参数
    const params = new URLSearchParams(props.location.search);
    const encodedContent = params.get('content');
    if (encodedContent) {
      // 解码回原始HTML字符串
      const decodedContent = decodeURIComponent(encodedContent);
      setContent(decodedContent);
    }
  }, [props.location.search]);

  // 注意:直接渲染HTML务必确保内容是可信的,防止XSS攻击!
  return <div dangerouslySetInnerHTML={{ __html: content }} />;
}

方案3:用localStorage/sessionStorage临时存储(适合长HTML内容)

在点击链接时把HTML内容存入本地存储,新页面读取后再删除,避免残留:

// Component 1
import { Link } from 'react-router-dom';

const handleLinkClick = () => {
  const htmlContent = "<div>....</div>";
  // 存入localStorage,sessionStorage会在浏览器关闭后自动清除,按需选择
  localStorage.setItem('component2_content', htmlContent);
};

<Link 
  to="/somepath/xyz" 
  target="_blank" 
  rel="noopener noreferrer" 
  className="..." 
  onClick={handleLinkClick}
/>
// Component 2
import { useEffect, useState } from 'react';

function Component2() {
  const [content, setContent] = useState('');

  useEffect(() => {
    // 从localStorage读取内容
    const storedContent = localStorage.getItem('component2_content');
    if (storedContent) {
      setContent(storedContent);
      // 读取后立即删除,避免其他页面误读取
      localStorage.removeItem('component2_content');
    }
  }, []);

  // 同样注意XSS风险,确保内容可信!
  return <div dangerouslySetInnerHTML={{ __html: content }} />;
}
重要提醒

无论用哪种方案渲染HTML字符串,都要确保内容是完全可信的(比如是后端生成或你自己控制的内容),否则直接用dangerouslySetInnerHTML会有XSS攻击的风险。如果内容包含用户输入,一定要先做HTML过滤处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:42:10