getStaticProps+GraphQL无限滚动异常:预加载数据未生效
问题分析与修复方案
你的核心问题是SWR的预加载fallback数据未被useSWRInfinite正确识别,导致初始pokemonList为undefined,进而触发重复请求。结合你预加载48只宝可梦的需求,以下是具体修复步骤:
1. 补充预加载数据(覆盖前48只)
当前getStaticProps只预加载了第一页24只,需要同时获取第二页数据并加入fallback:
export const getStaticProps: GetStaticProps = async () => { const limit = 24; // 生成两页的请求key const pageKeys = [ `species: pokemon_v2_pokemonspecies(order_by: {id: asc}, limit: ${limit}, offset: 0)`, `species: pokemon_v2_pokemonspecies(order_by: {id: asc}, limit: ${limit}, offset: ${limit})` ]; // 并行拉取两页数据 const [page1Data, page2Data] = await Promise.all( pageKeys.map(key => getPokemonListData({ url: key })) ); // 构建完整的fallback对象 const fallback = { [pageKeys[0]]: page1Data, [pageKeys[1]]: page2Data }; return { props: { fallback }, revalidate: 60 * 60 * 24 // 24小时 }; };
2. 给useSWRInfinite设置初始加载页数
默认情况下useSWRInfinite初始只加载1页,显式指定initialSize:2,让它直接读取预加载的两页数据:
const { data, error, size, setSize } = useSWRInfinite(getKey, url => getPokemonListData({ url }), { initialSize: 2 } // 对应预加载的两页48只 );
3. 处理pokemonList的空值状态
在列表渲染时添加空值判断,避免undefined.map()报错,同时确保SWR不会因渲染错误触发重复请求:
{pokemonList?.map((list, index) => ( <Fragment key={index}> {list.map(pokemon => ( <li key={pokemon.id}> <Pokemon id={pokemon.id} name={pokemon.name} types={pokemon.types} image={pokemon.image} /> </li> ))} </Fragment> ))}
核心问题总结
- 你只预加载了单页数据,但未配置
useSWRInfinite初始加载对应页数,导致预加载数据未被读取 - 未处理
pokemonList的初始undefined状态,可能引发渲染错误,触发SWR重新请求 - 若仍存在key匹配问题,检查
getKey生成的字符串与fallback中的key是否完全一致(包括空格、符号)
内容的提问来源于stack exchange,提问作者Sku
相关产品推荐
相关产品推荐

