介绍
几天前,我在这里发布了一个问题,寻求有关内容 API 的帮助,以对对象进行 javascript 查询,从那时起,我一直在努力理解有关 NextJS 使用此 API 的一件事。
这里的交易是contentful
package:getEntries()
和getEntry()
. 第一个确实帮助我获取了我正在工作的页面的内容,但我觉得由于内容模型的结构,我在访问此页面中的链接条目时遇到了问题。
工作代码
我已经contentfulClient
设置在一个单独的文件中,但为了解释起见,让我将两者连接起来:
import Head from 'next/head'
// ./lib/contentful-client.js
const { createClient } = require('contentful')
const contentfulClient = createClient({
space: process.env.NEXT_PUBLIC_CONTENTFUL_SPACE,
accessToken: process.env.NEXT_PUBLIC_CONTENTFUL_ACCESS_TOKEN
})
module.exports = contentfulClient
// ./pages/index.js
export async function getStaticProps() {
let data = await contenfulClient.getEntries({
content_type: 'page',
'field.slug': 'page_slug' // <-- this is being manually set for each page
})
return {
props: {
pagina: data.items[0] // <-- where the props are build and exported
}
}
}
export default function HomePage({ pagina }) {
const { title, slug, sections } = pagina.fields
return (
<div>
<Head>
<title>{title}</title>
</Head>
<main id={slug}>
{sections.map((section) => {
console.log(section)
})}
</main>
</div>
)
}
这将为构建页面的每个部分获取内容。控制台会在一定程度上显示实际结构的日志,这就是问题所在。
内容模型结构
开发页面的实际内容模型是为了为用户提供灵活性,可以选择是否为某个部分提供图像附件,或者构建具有其他属性的另一个组件。
├── Page
| ├── title
| ├── slug
| └── section
| ├── title
| ├── slug
| ├── content
| └── components
| ├── imageComponent
| ├── formComponent
| └── extraComponent
. .
. .
. .
使用前面的函数 getStaticProps(),映射部分的代码可以访问该组件数组,但不会返回它的内容:
// console output
{sys: {…}, fields: {…}}
fields:
componentes: Array(3)
0:
sys: {type: "Link", linkType: "Entry", id: "X1n2uZJfMMwtJbY3H7Z6M"}
__proto__: Object
1:
sys: {type: "Link", linkType: "Entry", id: "19gYv80phM75jgmAKCgwAI"}
__proto__: Object
2:
sys: {type: "Link", linkType: "Entry", id: "4xCKnCVG142Mxl9s1iNsPZ"}
__proto__: Object
length: 3
__proto__: Array(0)
因此,为了做到这一点,我意识到这getEntry(<entry_id>)
将是一种很好的方式来获取该内容,也许以某种方式将其转换为 json 结构。
// ./pages/index.js
return (
<div>
<Head>
<title>{title}</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main id={slug}>
{secoes.map((secao) => {
contentfulClient.getEntry(secao.sys.id)
.then((entry) => console.log(entry))
.catch((err) => console.error(err))
})}
</main>
<footer >
(footer)
</footer>
</div>
)
// console output
{sys: {…}, fields: {…}, toPlainObject: ƒ}
fields:
slug: "hero"
title: "This is my title!"
components: Array(3)
0:
fields:
main: Array(2)
0:
fields:
file:
contentType: "image/png"
details: {size: 188420, image: {…}}
fileName: "bkgHero.png"
url: "<path_to>/bkgHero.png" // <-- can reach the paths for images, for instance.
__proto__: Object
title: "heroBkg"
__proto__: Object
sys:
createdAt: "2020-06-08T15:18:42.394Z"
environment: {sys: {…}}
id: "5E2h7vNFAFTW4BYKWPJo9E"
locale: "pt-BR"
revision: 3
space: {sys: {…}}
type: "Asset"
updatedAt: "2020-06-30T19:05:51.537Z"
__proto__: Object
__proto__: Object
“破碎”的代码
嗯,它并没有真正坏掉。它记录下来,我可以看到这些对象的所有内容,但我不能指望它,因为.then()
promise 不会返回我似乎可以在我的页面中使用的值。
// ./pages/index.js
return (
<div>
<Head>
<title>{title}</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main id={slug}>
{secoes.map((secao) => {
contentfulClient.getEntry(secao.sys.id)
.then((entry) => <span>{entry.fields.slug}</span>) // <-- Trying to fetch content from that entry
.catch((err) => console.error(err))
})}
</main>
<footer >
(footer)
</footer>
</div>
)
控制台没有返回错误,并且我的页面结构不会使用该 slug 呈现跨度:
<div id="__next">
<div>
<main id="index"></main>
<footer>(footer)</footer>
</div>
</div>
这是一个已回答的问题,说明这getEntry()
是达到该内容的正确方法,我已经非常努力地尝试了这种方法,但没有成功。其他人说要查询getEntries()
并再次尝试,但没有成功。
我认为这里的主要问题是 NextJS 迫使我在索引中获取这些内容以通过道具传递给我的页面组件,理论上它应该以两种方式工作,因为两种方式都会在日志中返回我的内容。我只是无法将它作为道具或数据链。
不知道如何进行。我是否应该以另一种方式重新考虑整个事情,甚至尝试 GraphQL API?从来没有在盖茨比之外使用过,即使我不是专家。非常感谢您对此事的任何想法以及有关如何进行的建议。