Next.js getServerSideProps如何拆分数据配合fallback处理空props
问题原因
当前逻辑不生效有两个核心问题:
- GROQ联合查询只要执行不报错,就一定会返回包含
clients/videos/services三个属性的对象,哪怕videos查询结果是空数组,整个返回对象也不是falsy值,外层的if (!props)判断永远不会命中。 fallback: "blocking"是getStaticPaths的专属配置项,写在getServerSideProps的返回值中没有任何作用。
实现方案
不要对整个查询返回对象做非空判断,拿到返回结果后单独校验videos字段即可:
- 如果页面用服务端渲染(
getServerSideProps):直接判断videos是否为空数组/不存在,命中时返回404即可,不需要额外配置fallback。 - 如果用静态增量再生(需要
fallback:blocking能力):把配置迁移到getStaticPaths中,在getStaticProps里单独校验videos字段。
修正后的服务端渲染版本代码
import HomeComponent from "../components/Home"; import { sanityClient } from "../components/sanity"; export const getServerSideProps = async () => { const query = `{ 'clients': *[ _type == "clients"] { _id, client, mainImage, }, 'videos': *[ _type == "videos"] { id, title, url, }, 'services': *[ _type == "services"] { _id, title, description, mainImage, }, }`; const data = await sanityClient.fetch(query); // 单独判断videos字段:不存在或者长度为0时返回404 if (!data?.videos || data.videos.length === 0) { return { notFound: true, }; } return { props: data }; }; const Home= (props: any) => { return ( <> <HomeComponent {...props} /> </> ); }; export default Home;
注意:原代码中多余的嵌套props传递会让组件取值多一层嵌套,直接把查询结果作为props返回即可。
需要使用fallback:blocking的静态生成版本
需要新增getStaticPaths配置,同时把数据获取逻辑移到getStaticProps中:
import HomeComponent from "../components/Home"; import { sanityClient } from "../components/sanity"; // 配置fallback阻塞模式 export const getStaticPaths = async () => { return { paths: [], fallback: "blocking", } } export const getStaticProps = async () => { const query = `{ 'clients': *[ _type == "clients"] { _id, client, mainImage, }, 'videos': *[ _type == "videos"] { id, title, url, }, 'services': *[ _type == "services"] { _id, title, description, mainImage, }, }`; const data = await sanityClient.fetch(query); if (!data?.videos || data.videos.length === 0) { return { notFound: true, // 可选:配置revalidate实现ISR增量更新 revalidate: 60, }; } return { props: data, revalidate: 60, }; }; const Home= (props: any) => { return ( <> <HomeComponent {...props} /> </> ); }; export default Home;
内容的提问来源于stack exchange,提问作者Julia Schafer
相关产品推荐
相关产品推荐

