如何在Storyblok中仅当NewsTease块启用时调用API获取新闻预告?
解决方案
1. 在getStaticProps中按需请求新闻数据
先获取当前页面的Storyblok内容,遍历结构检查是否包含NewsTease组件,仅当检测到该组件时才调用新闻列表接口。
export async function getStaticProps(context) { const storyblokApi = getStoryblokApi(); // 先拉取当前页面的基础数据 const { data: pageData } = await storyblokApi.get(`cdn/stories/${context.params.slug}`, { version: process.env.NODE_ENV === 'production' ? 'published' : 'draft' }); let newsData = null; // 递归遍历页面组件,检查是否存在NewsTease块 const hasNewsTease = (components) => { if (!components) return false; for (const comp of components) { if (comp.component === 'NewsTease') { // 需与Storyblok中定义的组件名一致 return true; } // 处理嵌套组件的情况,继续递归检查 if (comp.body && hasNewsTease(comp.body)) { return true; } } return false; }; // 存在NewsTease块时才请求新闻数据 if (hasNewsTease(pageData.story.content.body)) { const { data: newsOverview } = await storyblokApi.get('cdn/stories', { content_type: "news", excluding_fields: "body", version: process.env.NODE_ENV === 'production' ? 'published' : 'draft' }); newsData = newsOverview.stories; } return { props: { story: pageData.story, newsData // 将新闻数据作为独立props返回 }, revalidate: 60 }; }
2. 直接传递数据给<NewsOverview>组件
在页面组件中,跳过StoryblokComponent对NewsTease的默认渲染,直接将newsData传入自定义的<NewsOverview>组件:
import StoryblokComponent from '@storyblok/react'; import NewsOverview from '../components/NewsOverview'; export default function Page({ story, newsData }) { const renderComponent = (blok) => { if (blok.component === 'NewsTease') { // 直接渲染NewsOverview并传入新闻数据 return <NewsOverview news={newsData} />; } // 其他组件保持StoryblokComponent的默认渲染逻辑 return <StoryblokComponent blok={blok} />; }; return ( <div> {story.content.body.map((blok) => renderComponent(blok))} </div> ); }
核心要点
- 递归检测组件:确保能找到嵌套在其他组件(如Section、Grid)内部的
NewsTease块,避免漏判。 - 按需请求:减少不必要的API调用,优化页面构建性能。
- 直接传参:绕过Storyblok组件的默认传参逻辑,采用React常规的组件传参方式,更直观可控。
内容的提问来源于stack exchange,提问作者Sandro Mennel
相关产品推荐
相关产品推荐

