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

在其他组件中嵌入React-Sigma-v2组件出现‘容器无宽度’错误求助

解决react-sigma嵌入Accordion时的「容器无宽度」错误

问题背景

单个MyGraph组件渲染正常,但通过Array.map批量嵌入react-bootstrap的Accordion.Body时,抛出错误:

Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.

已尝试为所有容器、组件设置固定宽高,导入样式表,但问题仍存在。经测试,推测原因是:

  • Accordion默认折叠,内部容器初始未进入可视DOM,尺寸为0,Sigma初始化无法检测到有效宽高
  • 批量渲染时多实例的初始化时机冲突(类似leaflet.js的多实例渲染问题)

解决方案

1. 延迟渲染:仅在Accordion展开时渲染图表

利用Accordion的展开状态控制MyGraph的渲染时机,确保Sigma初始化时容器已具备有效尺寸:

// 父组件代码
import { useState } from 'react';
import Accordion from 'react-bootstrap/Accordion';

export const GraphAccordion = ({ data }) => {
  const [expandedKey, setExpandedKey] = useState(null);

  return (
    <Accordion activeKey={expandedKey} onSelect={setExpandedKey}>
      {data.map((element, index) => (
        <Accordion.Item key={element.id || index} eventKey={String(index)}>
          <Accordion.Header>图表 {index + 1}</Accordion.Header>
          <Accordion.Body
            style={{ width: "500px", height: "500px", backgroundColor: "green" }}
          >
            <div style={{ width: "500px", height: "500px" }}>
              {/* 仅当当前项展开时才渲染图表 */}
              {expandedKey === String(index) && <MyGraph data={element} />}
            </div>
          </Accordion.Body>
        </Accordion.Item>
      ))}
    </Accordion>
  );
};

同时修正MyGraph组件,确保样式属性正确传递:

// MyGraph组件代码
export const MyGraph = ({ data, style = {} }) => {
  const graph = treatData(data);

  return (
    <SigmaContainer 
      graph={graph} 
      style={{ height: "500px", width: "500px", ...style }}
    >
      <ControlsContainer position="bottom-right">
        {/* 控件内容 */}
      </ControlsContainer>
    </SigmaContainer>
  );
};

2. 允许无效容器+展开时强制刷新

如果需要预渲染图表,先通过allowInvalidContainer规避初始化错误,再在Accordion展开时触发Sigma重绘:

// MyGraph组件添加ref和allowInvalidContainer
import { useRef, useEffect } from 'react';

export const MyGraph = ({ data, graphKey }) => {
  const graph = treatData(data);
  const sigmaRef = useRef(null);

  // 对外暴露刷新方法
  useEffect(() => {
    window[`sigma_${graphKey}`] = () => {
      sigmaRef.current?.getSigmaInstance()?.refresh();
    };
  }, [graphKey]);

  return (
    <SigmaContainer 
      ref={sigmaRef}
      graph={graph} 
      style={{ height: "500px", width: "500px" }}
      allowInvalidContainer={true}
    >
      <ControlsContainer position="bottom-right">
        {/* 控件内容 */}
      </ControlsContainer>
    </SigmaContainer>
  );
};
// 父组件调用刷新方法
export const GraphAccordion = ({ data }) => {
  const [expandedKey, setExpandedKey] = useState(null);

  const handleExpand = (key) => {
    setExpandedKey(key);
    // 延迟执行,确保DOM已完成尺寸更新
    setTimeout(() => {
      window[`sigma_${key}`]?.();
    }, 100);
  };

  return (
    <Accordion activeKey={expandedKey} onSelect={handleExpand}>
      {data.map((element, index) => (
        <Accordion.Item key={element.id || index} eventKey={String(index)}>
          <Accordion.Header>图表 {index + 1}</Accordion.Header>
          <Accordion.Body
            style={{ width: "500px", height: "500px", backgroundColor: "green" }}
          >
            <div style={{ width: "500px", height: "500px" }}>
              <MyGraph data={element} graphKey={String(index)} />
            </div>
          </Accordion.Body>
        </Accordion.Item>
      ))}
    </Accordion>
  );
};

3. 强制容器初始尺寸可见

给包裹MyGraph的容器设置强制可见的CSS(用visibility而非display),确保Sigma初始化时能检测到尺寸:

// 父组件中包裹MyGraph的div样式
<div 
  style={{ 
    width: "500px", 
    height: "500px", 
    visibility: expandedKey === String(index) ? "visible" : "hidden",
    overflow: "hidden"
  }}
>
  <MyGraph data={element} />
</div>

核心原因

Sigma图表初始化时需要读取容器的实际offsetWidth和offsetHeight,而Accordion折叠状态下,内部元素的尺寸为0,导致Sigma抛出错误。通过控制渲染时机、强制刷新或确保初始化时容器有有效尺寸,即可解决该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 22:15:41