将旧React项目迁移至NextJS时全局liquidDonutChart未定义问题求助
解决Next.js中引入全局脚本liquidDonutChart时"liquidDonutChart is not defined"的问题
问题根源
- 你使用了
strategy="lazyOnload"加载脚本,该策略会在页面空闲时才加载资源,但LiquidChart组件渲染时脚本尚未加载完成,导致调用liquidDonutChart时出现未定义错误。 d3.min.js是liquidDonutChart的依赖,未确保两者的加载顺序,可能出现依赖先于核心脚本加载的情况。
解决步骤
1. 调整脚本加载策略与依赖顺序
将脚本的加载策略改为beforeInteractive(确保在组件渲染前加载完成),同时指定依赖关系保证d3先加载:
import { GET } from '@/utils/api'; import { LiquidChart } from './LiquidChart'; import Script from 'next/script'; export async function Temperature() { const tempInfo = await GET('api/getTemp'); const { ChartData } = tempInfo; const chart = JSON.parse(ChartData); return ( <div className="flex h-[200px] w-[168px] flex-col items-center justify-center rounded-lg bg-wt-white p-2"> {/* 先加载d3依赖,设置id用于后续脚本关联 */} <Script src="d3.min.js" strategy="beforeInteractive" id="d3-script" /> {/* 依赖d3加载完成后再加载liquidDonutChart */} <Script src="liquidDonutChart.min.js" strategy="beforeInteractive" dependsOn="d3-script" /> <div className="flex h-[148px] w-[148px] items-center justify-center rounded-[50%] bg-wt-smoke"> <LiquidChart {...{ chart }} /> </div> </div> ); }
2. 在客户端组件中延迟初始化图表
修改LiquidChart组件,使用useEffect确保脚本加载完成后再调用liquidDonutChart,同时避免重复渲染问题:
'use client'; import { useEffect, useRef } from 'react'; export function LiquidChart({ chart }) { const liquidGaugeRef = useRef(null); const liquidDonutOptions = { showBG: false, animate: true, biggerLiquidDonut: false, noHoverOnChartBars: true, disableTooltip: true, arcWidthBase: null, arcWidthHover: null, }; useEffect(() => { // 确保全局变量存在、图表数据有效且DOM元素已挂载 if (chart && window.liquidDonutChart && liquidGaugeRef.current) { // 清空DOM避免重复初始化 liquidGaugeRef.current.innerHTML = ''; window.liquidDonutChart(`#${liquidGaugeRef.current.id}`, chart, liquidDonutOptions); } }, [chart]); return ( <div ref={liquidGaugeRef} id="liquid-gauge" style={{ width: '145px', height: '145px' }} className="dashboard-chart" /> ); }
3. 可选:消除TypeScript类型提示错误
在项目根目录创建global.d.ts文件,添加全局变量声明:
declare global { interface Window { liquidDonutChart: (selector: string, data: unknown, options: unknown) => void; } } export {};
添加后即可移除// @ts-expect-error注释。
额外检查
确保d3.min.js和liquidDonutChart.min.js放在Next.js的public目录下,否则会出现脚本加载404错误。
内容的提问来源于stack exchange,提问作者J4v4Scr1pt
相关产品推荐
相关产品推荐

