问题排查:Next.js中getStaticProps未提前加载且数据未传入Sidebar
问题排查与解决
核心问题1:getStaticProps 仅在Next.js页面组件中生效
getStaticProps 是Next.js专属的数据获取方法,只有和pages目录下的页面组件一起导出时,才会被框架识别并执行。你的代码里把它和普通组件Sidebar绑定导出,Next.js不会触发这个方法。
解决方法:
把getStaticProps迁移到页面组件(比如pages/index.js)中,再将获取到的plots作为props传递给Sidebar。
示例页面组件代码:
// pages/index.js import React, { useState } from "react"; import Sidebar from '../components/Sidebar'; import { fetchData } from '../utils/dataUtils'; // 可将fetchData抽离到单独文件 import { scaleLinear, quantile } from 'd3'; export async function getStaticProps() { try { const keyValues = await fetchData(); const plots_a = {}; const width = 300; // 定义width变量,可根据需求调整 for (const key in keyValues) { // 将CSV字符串数据转为数值,过滤无效值 const data = keyValues[key].map(Number).filter(n => !isNaN(n)); const sortedData = data.sort((a, b) => a - b); const p5 = quantile(sortedData, 0.05); const p95 = quantile(sortedData, 0.95); const xS = scaleLinear().domain([p5, p95]).range([0, width]); plots_a[key] = { data, xScale: xS, }; } console.log(plots_a); return { props: { plots: plots_a } }; } catch (err) { console.error(err); return { props: {} }; } } export default function Home({ plots }) { // 根据实际业务逻辑初始化selectedCell状态 const [selectedCell, setSelectedCell] = useState({}); return ( <div> <Sidebar plots={plots} selectedCell={selectedCell} setSelectedCell={setSelectedCell} /> </div> ); }
核心问题2:width 变量未定义
原getStaticProps中直接使用width但未声明,会抛出错误中断执行,需要在方法内明确定义该变量的值。
核心问题3:CSV数据未转为数值类型
Papa.parse解析CSV得到的是字符串数组,d3.quantile需要数值数组才能正确计算分位数,否则会得到NaN导致xScale无效,需转换并过滤无效值:
const data = keyValues[key].map(Number).filter(n => !isNaN(n));
额外注意:静态资源路径问题
Next.js的静态资源必须放在public目录下,所以你的CSV文件要放在public/data_csv/singapore-tess.csv,这样fetch('/data_csv/singapore-tess.csv')才能正确访问。
优化后的fetchData函数(可选)
简化fetch逻辑,无需手动处理Reader和Decoder:
export const fetchData = async () => { const response = await fetch('/data_csv/singapore-tess.csv'); const csv = await response.text(); return new Promise((resolve, reject) => { Papa.parse(csv, { header: true, complete: (results) => { const output = {}; results.data.forEach(row => { Object.entries(row).forEach(([key, value]) => { if (!output[key]) output[key] = []; output[key].push(value); }); }); resolve(output); }, error: reject }); }); }
内容的提问来源于stack exchange,提问作者Reuben
相关产品推荐
相关产品推荐

