nextjs getStaticProps 在我的组件中不起作用
nextjs getStaticProps not working in my component
我有以下组件,然后将其导入并在页面中使用。不幸的是,我收到错误 error - TypeError: Cannot read property 'labels' of undefined
,data
和 options
在我将它们传递给 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} />
)
}
我有以下组件,然后将其导入并在页面中使用。不幸的是,我收到错误 error - TypeError: Cannot read property 'labels' of undefined
,data
和 options
在我将它们传递给 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} />
)
}