GetStaticProps 没有得到正确的结果 |下一个Js

发布于 2025-01-12 14:05:43 字数 6662 浏览 0 评论 0原文

我已经使用 NextJs 和 WordPress Headless CMS 使用 WP GraphQL 和 ACF 设置了一个项目。

在我的每一篇文章中,我都有一些自定义块,并且在其中一个块中我有一个图像字段。当我通过 WP GraphQL 调用属性时,它返回图像 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;
}

在我的 [ 中。 在 blog- article.js

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,
    }
  }
}

中,我循环遍历块,这会调用 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< /code> 文件如下:

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 文件中,它会返回正确的信息

I've set up a project using NextJs with WordPress Headless CMS using WP GraphQL and ACF.

Within each of my posts, I have some custom blocks and within one of these blocks I have an Image field. When I call the attributes through the WP GraphQL it returns the Image ID, I therefore need to fetch the URL from that given ID (which uses the getImageById function.

My folder structure is as below, the function I'm having an issue with is located in /components/universalImage.js, however if I move it to the /pages/[category_slug]/learn/[slug].js file it works correctly.

 - 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

My apis are located in /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;
}

Within my [slug].js file I'm calling the BlogArticle component:

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,
    }
  }
}

Within blog-article.js I loop through the blocks, which calls the Block.js file

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>
   )
}

This is my Block.js file, which is simplified to show the line that matters

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>;
    }
}

My images.js file is as follows:

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>
    )
}

Then my universalImage.js file is as follows:

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
      }
    }
  }

If I put the getImageById() function within the [slug].js file it returns the correct information.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

悸初 2025-01-19 14:05:43

getStaticProps 只能在页面组件(pages 文件夹内的组件)中使用,在常规组件中不会调用它。需要使用useEffect代替

getStaticProps can only be used in page components (components inside the pages folder), it's not called in regular components. Need to use useEffect instead

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文