如何解决如何在 Next.js 动态页面的 Chart.js/react-chartjs-2 组件中加载异步/承诺数据?
我正在为如何在 react-chartjs-2 折线图中呈现承诺数据而苦苦挣扎。
图表组件在动态 Next.js 页面 [coin].js 中呈现。基于生成的动态页面 slug,执行 API 获取以基于某些函数匹配加密货币代币行情,然后使用 id 获取价格数据的另一个端点。下面是端点的示例: https://api.coingecko.com/api/v3/coins/ethereum/market_chart?vs_currency=usd&days=7&interval=hourly 然后通过 makeCoinData 函数发送价格数据响应,其中 map 用于将时间戳和价格分离到单独的数组中,以便稍后输入图表标签和数据键。
这就是我卡住的地方,因为在 [coin].js 页面中呈现 CoinChart 组件之前,有一些处理需要继续进行。
我很难理解如何实现可能需要的内容。我的函数可能设置不正确,但不确定是否需要某种条件或状态代码,例如 useState 或 useEffect 在渲染前等待数据,或立即渲染并在收到数据后重新渲染(不确定哪个更可取,以确保最佳性能并最大限度地减少对数据的请求)。或者,如果这与使用 next/dynamic 或动态导入或只是不正确的函数设置有关。
目前,我收到 TypeError: Cannot read property 'prices' of undefined,我相信是由于在基于 [coin].js slug 的处理链之前,图表组件过早调用 makeChartData 函数完成。
这是相关的代码片段,我正在为标签和数据测试相同的价格数组。另外,我认为在 useEffect 中使用间隔没有意义,因为我只是想在用户页面加载时呈现一次数据(最终从全局/用户不可知的缓存/ useSWR 更新 x 分钟后到最小化 API 请求)但只是我根据示例摆弄的东西。
相关:我计划将 useSWR 与 getStaticProps 结合起来用于缓存和重新验证数据(例如上面的图表数据),因此非常感谢有关在使用 SWR 时能够解决图表渲染问题的设置的任何反馈。
CoinChart.js
import { Line } from 'react-chartjs-2';
export async function makeChartData(get7DayChartRes) {
const chartData = await get7DayChartRes;
let chartTimes,chartPrices = [];
//chartTimes = chartData.prices.map((x) => x[0]);
chartPrices = chartData.prices.map((x) => x[1]);
return chartPrices;
}
export const genData = async (get7DayChartRes) => ({
labels: makeChartData(get7DayChartRes),datasets: [
{
label: '$',fill: false,lineTension: 0.1,backgroundColor: 'rgba(75,192,0.4)',borderColor: 'rgba(75,1)',pointBorderWidth: 3,data: makeChartData(get7DayChartRes),},],});
const options = {
scales: {
yAxes: [
{
ticks: {
beginAtZero: true,};
const CoinChart = () => {
// const [data,setData] = useState(genData());
// useEffect(() => {
// const interval = setInterval(() => setData(genData()),5000);
// return () => clearInterval(interval);
// },[]);
return (
<div>
<Line data={data} options={options} />
</div>
);
};
export default CoinChart;
[硬币].js 没有所有导入的代码:
export async function getStaticProps({ params }) {
const coinSlug = await getAllCoinPageData(params.coin);
const coinSlugString = await coinSlug.coin;
let specCoinResponse = '';
specCoinResponse = await getSpecCoinData(coinSlug);
const coinTicker = await getSpecCoinTickerForGecko(coinSlug);
const getCoinGeckoId = await getCoinGeckoCoinId(coinTicker);
const get7DayChartRes = await get7DayChartData(getCoinGeckoId);
const coinPrice7Day = await makeChartData(get7DayChartRes);
console.log(coinPrice7Day);
let coinName = await coinSlugString;
coinName = coinName
.toLowerCase()
.split(' ')
.map((s) => s.charat(0).toupperCase() + s.substring(1))
.join(' ');
return {
props: {
coinName: coinName,specCoinResponse: specCoinResponse,};
}
export async function getStaticPaths() {
const paths = await getAllCoinNames();
return { paths,fallback: true };
}
export default function CoinPage({ coinName,specCoinResponse }) {
const router = useRouter();
if (router.isFallback) {
return <h1>Loading...</h1>;
}
return (
<div> ... <CoinChart /> ...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。