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代替