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

React useState更新后自定义节点属性未同步渲染问题

问题根因

这是典型的闭包旧值问题:default_config是组件首次加载时定义的常量,其中viewGenerator渲染函数在初始化时就捕获了当时的circleR初始值("50")。后续setCircleR触发组件重渲染时,你传给<Graph>的config引用没有发生变化,react-d3-graph不会重新执行viewGenerator生成新的节点内容,所以自定义节点里读取到的永远是初始化时捕获的旧状态值。


可落地方案

方案1:显式传参+更新config引用(改造成本低)

不要让CustomNode读取外层闭包的circleR,把半径值作为显式props传入节点,同时在circleR变化时更新config引用,触发Graph重绘节点:

  1. 修改CustomNode,从props取半径值:
function CustomNode(props) {
  return (
    <div>
      <svg viewBox="-1 -1 2 2">
        <circle
          cx="0"
          cy="0"
          r={props.circleR}
          strokeWidth="0.1"
          stroke="black"
          fill="orange"
        />
      </svg>
    </div>
  );
}
  1. 用useMemo生成动态config,依赖circleR确保状态更新时生成新的config引用,同时把最新的半径值传入节点:
const graphConfig = useMemo(() => ({
  ...default_config.d3_config,
  node: {
    ...default_config.d3_config.node,
    viewGenerator: (node) => (
      <CustomNode node={node} focusId={null} circleR={circleR} />
    )
  }
}), [circleR]);
  1. 渲染Graph时传入动态生成的config,同时绑定缩放回调:
<Graph
  config={graphConfig}
  onZoomChange={zoomChange}
/>

方案2:节点内部维护状态(性能更优)

如果不想每次缩放都触发全图表重绘,可以直接把缩放监听逻辑下沉到CustomNode内部,绕开外层闭包问题:

import { useTransformContext } from 'react-zoom-pan-pinch';

function CustomNode(props) {
  const [circleR, setCircleR] = useState("50");
  // 直接从zoom-pan-pinch的上下文取最新的缩放状态
  const { transformState } = useTransformContext();

  useEffect(() => {
    setCircleR(transformState.scale > 1.311 ? "10" : "50");
  }, [transformState.scale]);

  return (
    <div>
      <svg viewBox="-1 -1 2 2">
        <circle
          cx="0"
          cy="0"
          r={circleR}
          strokeWidth="0.1"
          stroke="black"
          fill="orange"
        />
      </svg>
    </div>
  );
}

这种方案不需要修改外层config逻辑,缩放时只会更新对应节点本身,不会触发整个图表重绘。


补充提示:你贴的配置里写了minZoom: 1, maxZoom: 1,这会完全禁用缩放交互,记得根据业务需求调整缩放范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:09:18