Lui*_*dev 15 javascript typescript reactjs next.js apexcharts
我正在尝试将 apexcharts 用于 next.js 应用程序,但它返回窗口未定义。
\n我希望得到任何帮助。
\n有人知道发生了什么以及为什么吗?
\nimport React from 'react';\nimport Chart from 'react-apexcharts';\n\nexport default class Graficos extends React.Component <{}, { options: any, series: any }> {\n constructor(props:any) {\n super(props);\n\n this.state = {\n options: {\n chart: {\n id: "basic-bar"\n },\n xaxis: {\n categories: [1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999]\n }\n },\n series: [\n {\n name: "series-1",\n data: [30, 40, 45, 50, 49, 60, 70, 91]\n }\n ]\n };\n }\n \n render() {\n return (\n <div className="row">\n <h1>Gr\xc3\xa1fico B\xc3\xa1sico</h1>\n <div className="mixed-chart">\n <Chart\n options={this.state.options}\n series={this.state.series}\n type="bar"\n width={500}\n />\n </div>\n </div>\n );\n }\n }\nRun Code Online (Sandbox Code Playgroud)\n
小智 40
Next.js 的关键功能之一是它可以在服务器上甚至在构建时渲染 React 应用程序的部分内容。虽然这有助于提高页面的性能,但缺点是服务器不提供应用程序在浏览器中可以访问的所有相同的 API。在这种情况下,没有window定义全局对象。
不幸的是,搜索 apexcharts.js 的源代码会发现许多对以下内容的引用window:https://github.com/apexcharts/apexcharts.js/search?q = window。这也发生在他们的 React 包装器中:https://github.com/apexcharts/react-apexcharts/blob/ecf67949df058e15db2bf244e8aa30d78fc8ee47/src/react-apexcharts.jsx#L5。虽然似乎没有办法获取 apexcharts 来避免引用window,但您可以阻止 Next.js 使用服务器上的图表。最简单的方法是包装对代码的任何引用,检查是否已window定义,例如
<div className="mixed-chart">
{(typeof window !== 'undefined') &&
<Chart
options={this.state.options}
series={this.state.series}
type="bar"
width={500}
/>
}
</div>
Run Code Online (Sandbox Code Playgroud)
对于 apexcharts,您还需要对组件导入执行此操作,因为单独导入将触发对window第二个链接中所示的引用。为了解决这个问题,您需要使用动态导入,而不是当前使用的普通导入: https: //nextjs.org/docs/advanced-features/dynamic-import
import dynamic from 'next/dynamic'
const Chart = dynamic(() => import('react-apexcharts'), { ssr: false });
Run Code Online (Sandbox Code Playgroud)
在Next.js 13中使用 TypeScript 进行动态导入时,我遇到了类型不匹配问题。不过,我通过创建一个名为 ApexChart 的新组件解决了这个问题。
在新的 ApexChart 组件中,我导入了react-apexcharts库并将所需的属性传递给它。以下是该组件的示例:
"use client";
import { useEffect, useState } from "react";
export default function ApexChart(props: any) {
const [Chart, setChart] = useState<any>();
const hasType = typeof props?.type !== "undefined";
useEffect(() => {
import("react-apexcharts").then((mod) => {
setChart(() => mod.default);
});
}, []);
return hasType && Chart && <Chart {...props} />;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
34951 次 |
| 最近记录: |