在我的基于Next.js的网站中,需要在构建时从一个API中获取数据。
我尝试了各种解决方案,都没有成功。后来经过大量的研究和试验,这就是有效的方法。
这个解决方案在localhost(开发)和Vercel(生产)上都可以使用。
情况是这样的:我把 "会员 "的电子邮件储存在某个地方。它可以是一个远程数据库,Airtable,任何东西。
我只想下载一次这些数据,然后让它在网站上可用,直到我触发下一次构建。
这个成员名单是非常静态的。它可能最多一天改变一次。如果这个列表发生变化,我将使用他们的部署钩子在Vercel上以编程方式触发一次重新部署。
计划是这样的。我们将在一个.members 文件中创建一个本地数据缓存。
lib/members.js 文件中的一个函数将负责获取数据,并在第一次调用时将其作为JSON存储在缓存中,随后它将从缓存中读取数据。
import fs from 'fs'
import path from 'path'
function fetchMembersData() {
console.log('Fetching members data...')
return [{ email: 'test1@email.com' }, { email: 'test12@email.com' }]
}
const MEMBERS_CACHE_PATH = path.resolve('.members')
export default async function getMembers() {
let cachedData
try {
cachedData = JSON.parse(
fs.readFileSync(path.join(__dirname, MEMBERS_CACHE_PATH), 'utf8')
)
} catch (error) {
console.log('Member cache not initialized')
}
if (!cachedData) {
const data = fetchMembersData()
try {
fs.writeFileSync(
path.join(__dirname, MEMBERS_CACHE_PATH),
JSON.stringify(data),
'utf8'
)
console.log('Wrote to members cache')
} catch (error) {
console.log('ERROR WRITING MEMBERS CACHE TO FILE')
console.log(error)
}
cachedData = data
}
return cachedData
}
现在,在任何页面内,我们可以添加
import getMembers from 'lib/members'
并在getStaticProps() 。
const members = await getMembers()
现在有了这些数据,我们就可以做我们想做的事情。
一个快速的例子是将members 添加到由getStaticProps 返回的props 对象中,将其添加到页面组件接收的props中,我们可以在页面中对其进行迭代。
{members?.map((member) => {
return (
<p key={member.email} className='mt-3'>
{member.email}
</p>
)
})}