nextjs getStaticProps 在我的组件中不起作用

nextjs getStaticProps not working in my component

我有以下组件,然后将其导入并在页面中使用。不幸的是,我收到错误 error - TypeError: Cannot read property 'labels' of undefineddataoptions 在我将它们传递给 ChartCard 的行中带有下划线。我试着尽可能地遵循文档,但我想我一定是做错了什么。

import faker from '@faker-js/faker'
import {
  CategoryScale,
  Chart as ChartJS,
  Legend,
  LinearScale,
  LineElement,
  PointElement,
  Title,
  Tooltip,
} from 'chart.js'
import { Line } from 'react-chartjs-2'
import BaseCard from './BaseCard'

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
)
export async function getStaticProps() {
  const options = {
    responsive: true,
    plugins: {
      legend: {
        position: 'top' as const,
      },
      title: {
        display: true,
        text: 'Price',
      },
    },
  }
  const labels = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
  ]
  const data = {
    labels,
    datasets: [
      {
        label: 'Dataset 1',
        data: labels.map(() => faker.datatype.number({ min: 2000, max: 4000 })),
        borderColor: 'rgb(255, 99, 132)',
        backgroundColor: 'rgba(255, 99, 132, 0.5)',
      },
    ],
  }

  return {
    props: { options, data },
  }
}


export default function ChartCard({ options, data }) {
  return (
    <BaseCard>
      <Line options={options} data={data} />
    </BaseCard>
  )
}

编辑:我现在重构了我的代码,使 index.js 页面中的 getStaticProps 如下所示:

#index.tsx
import type { NextPage } from 'next'
import faker from '@faker-js/faker'
import ChartCard from '../components/ChartCard'

export async function getStaticProps() {
  const options = {
    responsive: true,
    plugins: {
      legend: {
        position: 'top' as const,
      },
      title: {
        display: true,
        text: 'IndexCoin Price',
      },
    },
  }
  const labels = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
  ]
  const data = {
    labels,
    datasets: [
      {
        label: 'Dataset 1',
        data: labels.map(() => faker.datatype.number({ min: 2000, max: 4000 })),
        borderColor: 'rgb(255, 99, 132)',
        backgroundColor: 'rgba(255, 99, 132, 0.5)',
      },
    ],
  }

  return {
    props: { options, data },
  }
}

const Home: NextPage = (options, data) => {
  console.log(options)
  console.log(data)
  console.log(data.datasets)
  return(
    <ChartCard options={options} data={data} />
  )
}

控制台输出为:

options: { responsive: true, plugins: { legend: [Object], title: [Object] } },
  data: {
    labels: [
      'January', 'February',
      'March',   'April',
      'May',     'June',
      'July'
    ],
    datasets: [ [Object] ]
  }
}
{}
undefined

这会崩溃,因为数据集未定义。为什么会这样?

您只能在 NextJS 页面(即 src/pages/MyPageComponent.js 下的组件)中使用 getStaticProps

(https://nextjs.org/docs/basic-features/data-fetching/get-static-props)

这意味着您的 ChartCard 正在使用 options=undefined 和 data=undefined 调用,因为 getStaticProps 永远不会运行。

如果能够将 server-side 数据获取和呈现封装在一个组件文件中当然会很好,但不幸的是,现在这是不可能的。

您需要做的是添加一个 api 到例如src/api/MyApi.js 并在您的组件中调用它。

例如一个简单的例子开始于:

src/api/MyApi.js

export default function MyApi(req, res) {
  //... do your data fetching
  res.send({options, data})
}

src/components/MyComponent.js

const [result, setResult] = useState();
useEffect(async ()=>{
  const res = await fetch('/api/MyApi');
  const result = await res.json();
  setResult(result);
}, []);

const {options, data} = result ?? {};

注意以上将执行 client-side 数据获取,因此需要一个实时服务器。

如果您希望在构建时构建静态页面,那么您唯一的选择 (IIRC) 是捕获 src/pages/MyPage.js 的 getStaticProps 中所需的所有数据,并根据需要将它们传递到页面的组件中.

如果此代码与您的项目完全相同,则其中有错别字:

position: 'top' as const

试试这个:

position: 'top as const'

并且还对页面组件使用 getStaticProps

在我看来,props 是一个对象,因此请按以下方式更改您的代码;

const Home: NextPage = ({options, data}) => {
  console.log(options)
  console.log(data)
  console.log(data.datasets)
  return(
    <ChartCard options={options} data={data} />
  )
}