GetStaticProps 没有得到正确的结果 |下一步
GetStaticProps not getting correct result | NextJs
我已经使用 WP GraphQL 和 ACF 使用 NextJs 和 WordPress Headless CMS 建立了一个项目。
在我的每个帖子中,我都有一些自定义块,在其中一个块中我有一个图像字段。当我通过 WP GraphQL 调用属性时,它 returns 图像 ID,因此我需要从给定的 ID 中获取 URL(它使用 getImageById
函数。
我的文件夹结构如下,我遇到问题的函数位于 /components/universalImage.js
,但是如果我将它移动到 /pages/[category_slug]/learn/[slug].js
文件,它可以正常工作。
- components
- blocks
- images.js
(other blocks in here)
- pageTemplates
- Blog
- blog-article.js
- Block.js
- universalImage.js
- lib
- api.js
- pages
- [category_slug]
- learn
-[slug].js
我的 API 位于 /lib/api.js
---API.js File---
export async function getImageById(id) {
const data = await fetchAPI(
`
query GetImageDetails($id: Int!) {
mediaItems(where: {id: $id}) {
nodes {
mediaItemUrl
mediaItemId
}
}
}
`,
{
variables: {
'id': id,
}
}
)
return data;
}
async function fetchAPI(query, { variables } = {}) {
// Set up some headers to tell the fetch call
// that this is an application/json type
const headers = { 'Content-Type': 'application/json' };
// build out the fetch() call using the API_URL
// environment variable pulled in at the start
// Note the merging of the query and variables
const res = await fetch(API_URL, {
method: 'POST',
headers,
body: JSON.stringify({ query, variables })
});
// error handling work
const json = await res.json();
if (json.errors) {
console.log(json.errors);
console.log('error details', query, variables);
throw new Error('Failed to fetch API');
}
return json.data;
}
在我的 [slug].js
文件中,我正在调用 BlogArticle
组件:
import BlogArticle from '../../../components/pageTemplates/Blog/blog-article'
import { getAllPosts, getAllPostsWithSlug, getPost, moreLikeThis } from '../../../lib/api'
export default function WebDesignPost({postData, moreLike}) {
let postDataArray;
postDataArray = {
'postData' : postData,
'moreLike' : {
"type" : 'More like this',
"posts" : moreLike
}
}
return (
<BlogArticle post={postDataArray}></BlogArticle>
)
}
export async function getStaticPaths() {
const allPosts = await getAllPostsWithSlug();
const allPostsJson = await allPosts;
return {
paths: allPosts.edges.map(({node}) => `/${node.categories.nodes[0].slug}/learn/${node.slug}`) || [],
fallback: false
};
}
export async function getStaticProps({ params: {category_slug, slug}}) {
const data = await getPost(slug);
const moreLike = await moreLikeThis(data.post.categories.nodes[0].categoryId);
return {
props: {
data,
postData: data.post,
moreLike,
}
}
}
在 blog-article.js
中循环遍历块,调用 Block.js
文件
import Head from 'next/head'
import Header from '../../../components/header'
import Image from 'next/image'
import Block from '../../Block'
import { useRouter } from 'next/router'
import Link from 'next/link'
export default function BlogArticle(post) {
const router = useRouter();
let caption;
const data = post.post.postData;
return (
<div>
{router.isFallback ? (
<h2>Loading...</h2>
) : (
<div>
<Head></Head>
<Header></Header>
<main className="container">
<section className="blogHeader">
<div className="blogHeaderContainer">
<h1>{data.title}</h1>
</div>
</section>
<div>
{data.blocks ? data.blocks.map((blocks, index) => <Block block={blocks.name} key={index} attributes={blocks}></Block>) : 'No Blocks on page' }
</div>
</main>
</div>
)}
</div>
)
}
这是我的 Block.js
文件,经过简化以显示重要的行
import Images from "./blocks/images";
export default function Block({block, attributes}) {
switch (block) {
case 'acf/images':
return <Images {...attributes}/>;
default:
return <div className="blockNotFound">Block not found - {block}</div>;
}
}
我的images.js
文件如下:
import styles from '../blockStyles/imagesBlock.module.scss'
import Image from 'next/image'
import { getImageById } from '../../lib/api';
import UniversalImage from '../universalImage'
export default function ImagesBlock(attributes) {
const parsedData = JSON.parse(attributes.attributesJSON).data;
let number = parsedData.images;
let image1 = parsedData.images_0_image;
let image1Title = parsedData.images_0_image_title;
let image2 = parsedData.images_1_image;
let image2Title = parsedData.images_1_image_title;
let imageDiv;
let image1Div =
<div>
<h3>{image1Title}</h3>
<UniversalImage imageID={image1}></UniversalImage>
</div>;
let image2Div =
<div>
<h3>{image2Title}</h3>
<UniversalImage imageID={image2}></UniversalImage>
</div>;
if (number == 2) {
imageDiv =
<div className={styles.doubleImages}>
{image1Div}
{image2Div}
</div>
} else {
imageDiv =
<div className={styles.singleImage}>
{image1Div}
</div>
}
return (
<section className={styles.imagesBlock}>
{imageDiv}
</section>
)
}
那么我的universalImage.js
文件如下:
import { getImageById } from '../lib/api'
export default function UniversalImage({imageID, jsonIM}) {
console.log(imageID)
// This prints the correct Image ID - i.e 14
console.log(jsonIM)
// This returns undefined
return (
<div>
<div className="blockNotFound">Got to Fix - Universal Image Block</div>
</div>
)
}
export async function getStaticProps({imageID}) {
const im = await getImageById(imageID);
const jsonIM = await im.json();
return {
props: {
jsonIM
}
}
}
如果我将 getImageById()
函数放在 [slug].js
文件中,它会 returns 正确的信息。
提前致谢!
getStaticProps
只能在页面组件(pages
文件夹内的组件)中使用,在常规组件中不会调用。需要用useEffect
代替
我已经使用 WP GraphQL 和 ACF 使用 NextJs 和 WordPress Headless CMS 建立了一个项目。
在我的每个帖子中,我都有一些自定义块,在其中一个块中我有一个图像字段。当我通过 WP GraphQL 调用属性时,它 returns 图像 ID,因此我需要从给定的 ID 中获取 URL(它使用 getImageById
函数。
我的文件夹结构如下,我遇到问题的函数位于 /components/universalImage.js
,但是如果我将它移动到 /pages/[category_slug]/learn/[slug].js
文件,它可以正常工作。
- components
- blocks
- images.js
(other blocks in here)
- pageTemplates
- Blog
- blog-article.js
- Block.js
- universalImage.js
- lib
- api.js
- pages
- [category_slug]
- learn
-[slug].js
我的 API 位于 /lib/api.js
---API.js File---
export async function getImageById(id) {
const data = await fetchAPI(
`
query GetImageDetails($id: Int!) {
mediaItems(where: {id: $id}) {
nodes {
mediaItemUrl
mediaItemId
}
}
}
`,
{
variables: {
'id': id,
}
}
)
return data;
}
async function fetchAPI(query, { variables } = {}) {
// Set up some headers to tell the fetch call
// that this is an application/json type
const headers = { 'Content-Type': 'application/json' };
// build out the fetch() call using the API_URL
// environment variable pulled in at the start
// Note the merging of the query and variables
const res = await fetch(API_URL, {
method: 'POST',
headers,
body: JSON.stringify({ query, variables })
});
// error handling work
const json = await res.json();
if (json.errors) {
console.log(json.errors);
console.log('error details', query, variables);
throw new Error('Failed to fetch API');
}
return json.data;
}
在我的 [slug].js
文件中,我正在调用 BlogArticle
组件:
import BlogArticle from '../../../components/pageTemplates/Blog/blog-article'
import { getAllPosts, getAllPostsWithSlug, getPost, moreLikeThis } from '../../../lib/api'
export default function WebDesignPost({postData, moreLike}) {
let postDataArray;
postDataArray = {
'postData' : postData,
'moreLike' : {
"type" : 'More like this',
"posts" : moreLike
}
}
return (
<BlogArticle post={postDataArray}></BlogArticle>
)
}
export async function getStaticPaths() {
const allPosts = await getAllPostsWithSlug();
const allPostsJson = await allPosts;
return {
paths: allPosts.edges.map(({node}) => `/${node.categories.nodes[0].slug}/learn/${node.slug}`) || [],
fallback: false
};
}
export async function getStaticProps({ params: {category_slug, slug}}) {
const data = await getPost(slug);
const moreLike = await moreLikeThis(data.post.categories.nodes[0].categoryId);
return {
props: {
data,
postData: data.post,
moreLike,
}
}
}
在 blog-article.js
中循环遍历块,调用 Block.js
文件
import Head from 'next/head'
import Header from '../../../components/header'
import Image from 'next/image'
import Block from '../../Block'
import { useRouter } from 'next/router'
import Link from 'next/link'
export default function BlogArticle(post) {
const router = useRouter();
let caption;
const data = post.post.postData;
return (
<div>
{router.isFallback ? (
<h2>Loading...</h2>
) : (
<div>
<Head></Head>
<Header></Header>
<main className="container">
<section className="blogHeader">
<div className="blogHeaderContainer">
<h1>{data.title}</h1>
</div>
</section>
<div>
{data.blocks ? data.blocks.map((blocks, index) => <Block block={blocks.name} key={index} attributes={blocks}></Block>) : 'No Blocks on page' }
</div>
</main>
</div>
)}
</div>
)
}
这是我的 Block.js
文件,经过简化以显示重要的行
import Images from "./blocks/images";
export default function Block({block, attributes}) {
switch (block) {
case 'acf/images':
return <Images {...attributes}/>;
default:
return <div className="blockNotFound">Block not found - {block}</div>;
}
}
我的images.js
文件如下:
import styles from '../blockStyles/imagesBlock.module.scss'
import Image from 'next/image'
import { getImageById } from '../../lib/api';
import UniversalImage from '../universalImage'
export default function ImagesBlock(attributes) {
const parsedData = JSON.parse(attributes.attributesJSON).data;
let number = parsedData.images;
let image1 = parsedData.images_0_image;
let image1Title = parsedData.images_0_image_title;
let image2 = parsedData.images_1_image;
let image2Title = parsedData.images_1_image_title;
let imageDiv;
let image1Div =
<div>
<h3>{image1Title}</h3>
<UniversalImage imageID={image1}></UniversalImage>
</div>;
let image2Div =
<div>
<h3>{image2Title}</h3>
<UniversalImage imageID={image2}></UniversalImage>
</div>;
if (number == 2) {
imageDiv =
<div className={styles.doubleImages}>
{image1Div}
{image2Div}
</div>
} else {
imageDiv =
<div className={styles.singleImage}>
{image1Div}
</div>
}
return (
<section className={styles.imagesBlock}>
{imageDiv}
</section>
)
}
那么我的universalImage.js
文件如下:
import { getImageById } from '../lib/api'
export default function UniversalImage({imageID, jsonIM}) {
console.log(imageID)
// This prints the correct Image ID - i.e 14
console.log(jsonIM)
// This returns undefined
return (
<div>
<div className="blockNotFound">Got to Fix - Universal Image Block</div>
</div>
)
}
export async function getStaticProps({imageID}) {
const im = await getImageById(imageID);
const jsonIM = await im.json();
return {
props: {
jsonIM
}
}
}
如果我将 getImageById()
函数放在 [slug].js
文件中,它会 returns 正确的信息。
提前致谢!
getStaticProps
只能在页面组件(pages
文件夹内的组件)中使用,在常规组件中不会调用。需要用useEffect
代替