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

Next.js/React实现右键新标签页传递接口值问题求助

问题分析与解决方案

你的代码存在几个核心问题,导致无法正确实现需求:

  1. 在事件处理函数内部调用useEffect——违反React Hooks规则,Hooks仅能在组件顶层或自定义Hook中使用
  2. 条件块内调用useState——同样违反Hooks规则,Hooks必须始终在组件顶层作用域执行
  3. 逻辑时机不合理——右键触发时的存储逻辑被错误包裹,且未处理数据残留问题

以下是修正后的完整实现:

import { useState, useEffect } from 'react';

// 假设你的接口定义
interface DealInterface {
  // 自定义字段
}

type EnterpriseDetailType = {
  // 自定义字段
};

const TargetComponent = () => {
  // 顶层初始化状态,从localStorage读取数据
  const [dealData, setDealData] = useState<DealInterface | null>(() => {
    const saved = localStorage.getItem('dealData');
    return saved ? JSON.parse(saved) as DealInterface : null;
  });
  const [iixValuesData, setIixValuesData] = useState<EnterpriseDetailType | null>(() => {
    const saved = localStorage.getItem('iixValuesData');
    return saved ? JSON.parse(saved) as EnterpriseDetailType : null;
  });
  const [hasNewPage, setHasNewPage] = useState<string | null>(localStorage.getItem('hasNewPage'));

  // 读取数据后立即清理localStorage,避免残留
  useEffect(() => {
    if (hasNewPage === 'Yes') {
      localStorage.removeItem('hasNewPage');
      localStorage.removeItem('dealData');
      localStorage.removeItem('iixValuesData');
      setHasNewPage(null);
    }
  }, [hasNewPage]);

  // 处理右键菜单事件
  const handleContextMenu = (e: React.MouseEvent, deal: DealInterface, iixValues: EnterpriseDetailType) => {
    // 不要阻止默认行为,保留浏览器右键菜单让用户选择"在新标签页打开"
    localStorage.setItem('hasNewPage', 'Yes');
    localStorage.setItem('dealData', JSON.stringify(deal));
    localStorage.setItem('iixValuesData', JSON.stringify(iixValues));
  };

  // 处理左键点击事件
  const handleLeftClick = (deal: DealInterface, iixValues: EnterpriseDetailType) => {
    console.log('Left click triggered');
    // 左键点击的自定义逻辑,比如路由跳转
  };

  // 新标签页加载完成后的业务逻辑
  useEffect(() => {
    if (dealData && iixValuesData && hasNewPage === 'Yes') {
      console.log('Received data from right-click:', dealData, iixValuesData);
      // 这里编写展示选中项的逻辑
    }
  }, [dealData, iixValuesData, hasNewPage]);

  return (
    <a
      href="/your-target-path"
      onClick={(e) => {
        e.preventDefault();
        handleLeftClick(dealData, iixValuesData);
      }}
      onContextMenu={(e) => handleContextMenu(e, dealData, iixValuesData)}
    >
      点击或右键打开链接
    </a>
  );
};

export default TargetComponent;

关键修正说明

  1. 移除事件内的Hooks调用:直接在onContextMenu事件中完成localStorage存储,无需借助useEffect
  2. 规范Hooks使用:所有useState和useEffect都放在组件顶层,符合React规则
  3. 类型安全处理:通过类型断言as DealInterface解决JSON.parse后的类型缺失问题
  4. 自动清理数据:新标签页读取数据后立即清除localStorage内容,避免残留数据干扰后续操作
  5. 保留默认右键菜单:不调用e.preventDefault(),让用户能正常选择"在新标签页打开"选项

可选优化

如果不需要数据持久化到浏览器关闭后,可以用sessionStorage替代localStorage,数据会在页面关闭时自动清除,进一步降低残留风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:10:32