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

React组件中TradingView Widget重复显示问题求助

解决TradingView Widget在React中重复显示的问题

问题现象

在React项目中通过自定义TradingViewWidget组件嵌入TradingView图表时,页面出现两个完全相同的Widget实例,已确认组件未触发重渲染,但重复问题依然存在。

TradingView Widget重复显示截图

原因分析

  1. TradingView的嵌入脚本会自动扫描页面中所有带有tradingview-widget-container__widget类名的元素,并在每个匹配元素中渲染图表组件。你在组件的JSX中手动添加了该类名的div,同时脚本挂载的容器也会被自动注入图表结构,导致两个实例同时渲染。
  2. 组件的useEffect没有清理逻辑,当组件卸载后重新挂载(比如路由切换),会重复创建脚本标签,进一步加剧重复渲染问题。

解决方案

  • 移除JSX中手动编写的tradingview-widget-container__widget元素,脚本会自动在挂载容器内生成所需DOM
  • 在useEffect中添加清理函数,组件卸载时移除创建的脚本标签,避免残留
  • 利用useRef标记脚本是否已添加,确保脚本只被创建一次

修改后的代码示例

TradingViewWidget.jsx

import React, { useEffect, useRef, memo } from "react";

function TradingViewWidget() {
  const container = useRef();
  const scriptAdded = useRef(false); // 标记脚本是否已添加

  useEffect(() => {
    // 避免重复添加脚本
    if (scriptAdded.current) return;

    const script = document.createElement("script");
    script.src =
      "https://s3.tradingview.com/external-embedding/embed-widget-symbol-overview.js";
    script.type = "text/javascript";
    script.async = true;
    script.innerHTML = `
        {
          "symbols": [
            [
              "BITSTAMP:BTCUSD|7D"
            ]
          ],
          "chartOnly": false,
          "width": "100%",
          "height": "100%",
          "locale": "en",
          "colorTheme": "light",
          "autosize": true,
          "showVolume": false,
          "showMA": false,
          "hideDateRanges": false,
          "hideMarketStatus": true,
          "hideSymbolLogo": false,
          "scalePosition": "left",
          "scaleMode": "Normal",
          "fontFamily": "Arial, sans-serif",
          "fontSize": "10",
          "noTimeScale": false,
          "valuesTracking": "1",
          "changeMode": "price-and-percent",
          "chartType": "area",
          "maLineColor": "#2962FF",
          "maLineWidth": 1,
          "maLength": 9,
          "gridLineColor": "rgba(91, 156, 246, 0.14)",
          "lineWidth": 2,
          "lineType": 0,
          "dateRanges": [
            "1d|3",
            "1w|1D",
            "1m|1D",
            "3m|1D",
            "6m|1D",
            "12m|1M",
            "all|12M"
          ],
          "lineColor": "rgba(91, 156, 246, 1)",
          "topColor": "rgba(187, 217, 251, 0.2)",
          "bottomColor": "rgba(255, 255, 255, 0.39)",
          "dateFormat": "dd MMM",
          "timeHoursFormat": "24-hours"
        }`;
    
    container.current.appendChild(script);
    scriptAdded.current = true;

    // 清理函数:组件卸载时移除脚本
    return () => {
      if (scriptAdded.current && container.current.contains(script)) {
        container.current.removeChild(script);
        scriptAdded.current = false;
      }
    };
  }, []);

  return (
    <div className="tradingview-widget-container flex justify-center mx-auto mt-5 lg:mt-0 border-4 border-red-500 min-w-96 h-96 md:w-5/6 md:h-3/4 lg:w-4/5 lg:h-[45rem]" ref={container}>
      <div className="tradingview-widget-copyright">
        <a
          href="https://www.tradingview.com/"
          rel="noopener nofollow"
          target="_blank"
        >
          <span className="blue-text">Track all markets on TradingView</span>
        </a>
      </div>
    </div>
  );
}

export default memo(TradingViewWidget);

关键修改点

  1. 移除了JSX中手动添加的<div className="tradingview-widget-container__widget"></div>,避免脚本重复渲染
  2. 添加scriptAdded ref标记脚本是否已创建,防止重复添加
  3. 在useEffect的返回函数中实现清理逻辑,组件卸载时移除创建的脚本标签

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 11:05:55