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

React问题:点击相机按钮第二次无法取消筛选,需第三次点击

问题分析

你的核心问题有两个:

  1. 点击同一按钮时useEffect不触发:useEffect依赖的是currentCam,当第二次点击同一相机按钮时,如果currentCam没有变化(比如redux里仍保留着之前的相机值),这个useEffect根本不会执行,自然无法触发取消筛选的逻辑。
  2. 状态更新异步导致逻辑混乱:在filterCamera里,你用当前的toggleSiteCheckmark.extendDetails值决定设置哪份数据,但setToggleSiteCheckmark是异步操作,状态不会立即更新,导致后续判断和实际状态不同步,第三次点击时才刚好凑齐状态变化的节奏。
修复方案

1. 调整按钮点击逻辑(关键)

确保点击同一相机按钮时能触发“取消选中”动作:如果currentCam是redux管理的,点击按钮时判断——若当前点击的相机和currentCam相同,就把currentCam设为null(取消筛选);否则设置为当前相机(激活筛选)。

2. 重构筛选逻辑,分离状态依赖

把筛选逻辑和toggle状态解绑,直接根据currentCam是否存在处理数据,去掉不必要的toggleSiteCheckmark状态,避免状态不同步问题。

修改后的代码示例:

import { Graph } from "react-d3-graph";

const visualGraph = useSelector((state: RootStateOrAny) => state.graph.graph);
const currentCam = useSelector((state: RootStateOrAny) => state.currentCam);
const [filteredGraphData, setFilteredGraphData] = useState(visualGraph);

// 仅在currentCam或原始图表数据变化时重新计算筛选结果
useEffect(() => {
  if (!currentCam) {
    // 无选中相机,恢复原始数据
    setFilteredGraphData(visualGraph);
    return;
  }

  // 筛选属于当前相机的节点
  const targetNodes = visualGraph.nodes.filter(
    (x: any) => x.camera === currentCam.identifier
  );
  const targetNodeIds = new Set(targetNodes.map(n => n.id));

  // 筛选关联的链接:source或target在目标节点中
  const filteredLinks = visualGraph.links.filter((x: any) => {
    return targetNodeIds.has(x.source) || targetNodeIds.has(x.target);
  });

  // 收集所有关联节点(避免遗漏链接指向的非相机节点)
  const allRelatedIds = new Set([
    ...targetNodeIds,
    ...filteredLinks.map(l => l.source),
    ...filteredLinks.map(l => l.target)
  ]);
  const allNodes = visualGraph.nodes.filter(n => allRelatedIds.has(n.id));

  setFilteredGraphData({ links: filteredLinks, nodes: allNodes });
}, [currentCam, visualGraph]);

// 渲染逻辑:有选中相机则用筛选后的数据,否则用原始数据
<Graph data={currentCam ? filteredGraphData : visualGraph} />

3. 按钮点击的redux动作示例(假设用redux-toolkit)

如果用redux管理currentCam,按钮点击事件需处理切换逻辑:

const handleCamClick = (cam) => {
  dispatch(setCurrentCam(currentCam?.identifier === cam.identifier ? null : cam));
};
额外优化点
  • 用Set存储节点ID,比includes循环效率更高(数据量大时更明显)。
  • 给filteredGraphData设置初始值为visualGraph,避免初始渲染出现空数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:45:55