You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13从Supabase取数建图片画廊遇‘Result is not iterable’错误

解决Next.js 13 App目录中generateStaticParams的“Result is not iterable”错误

你遇到的核心问题是用错了generateStaticParams的用途,这个函数不是用来替代getStaticProps传递页面数据的,而是专门给动态路由预生成路由参数的。App目录下获取静态数据的正确方式是直接在页面组件中使用async/await。

错误原因拆解

generateStaticParams的返回值要求是可迭代的参数数组(比如[{ id: 1 }, { id: 2 }]),用于生成动态路由的所有可能路径。但你现在返回的是类似getStaticProps的{ props: { ... } }对象,完全不符合该函数的要求,所以抛出“Result is not iterable”错误。

同时,App目录不再支持getStaticProps/getServerSideProps,所有数据获取逻辑需要放在组件内部或单独的异步函数中。

修正后的代码实现

1. 页面组件(app/products/page.tsx)

移除错误的generateStaticParams,改为在组件内异步获取数据,同时补充类型定义:

import { createClient } from '@supabase/supabase-js';
import Gallery from '@/components/Gallery';

// 定义匹配Supabase表结构的Image类型
type Image = {
  id: number;
  imageSrc: string;
  // 根据你的实际表结构补充其他字段
};

// 封装Supabase客户端初始化(可抽离到utils文件复用)
const getSupabaseAdmin = () => {
  return createClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL || '',
    process.env.SUPABASE_SERVICE_ROLE_KEY || ''
  );
};

// 页面组件改为async函数,直接在内部获取数据
export default async function ProductsPage() {
  const supabaseAdmin = getSupabaseAdmin();
  // 给data设置默认空数组,避免返回null时map报错
  const { data: images = [] } = await supabaseAdmin.from('images').select('*').order('id');
  
  return (
    <div>
      <Gallery images={images} />
    </div>
  );
}

2. Gallery组件(components/Gallery.tsx)

确保类型引用正确:

import BlurImage from './BlurImage';
// 导入Image类型,也可以把类型放到公共文件(如types/index.ts)统一管理
import type { Image } from '@/app/products/page';

export default function Gallery({ images }: { images: Image[] }) {
  return (
    <div className="mx-auto max-w-2xl py-16 px-4 sm:py-24 sm:px-6 lg:max-w-7xl lg:px-8">
      <div className="grid grid-cols-1 gap-y-10 gap-x-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 xl:gap-x-8">
        {images.map((image) => (
          <BlurImage key={image.id} image={image} />
        ))}
      </div>
    </div>
  );
}

3. BlurImage组件(components/BlurImage.tsx)

更新Image类型引用,并适配Next.js 13的Image组件API:

'use client';
import Image from 'next/image';
import { useState } from 'react';
import type { Image } from '@/app/products/page';

function cn(...classes: string[]) {
  return classes.filter(Boolean).join(' ');
}

function BlurImage({ image }: { image: Image }) {
  const [isLoading, setLoading] = useState(true);

  return (
    <div className="group">
      <div className="aspect-w-1 aspect-h-1 w-full overflow-hidden rounded-lg bg-gray-200 xl:aspect-w-7 xl:aspect-h-8">
        <Image
          alt="画廊图片" // 补充有意义的alt文本,提升可访问性
          src={image.imageSrc}
          fill // Next.js 13+推荐使用fill替代layout="fill"
          objectFit="cover"
          className={cn(
            'duration-700 ease-in-out group-hover:opacity-75',
            isLoading
              ? 'scale-110 blur-2xl grayscale'
              : 'scale-100 blur-0 grayscale-0'
          )}
          onLoadingComplete={() => setLoading(false)}
        />
      </div>
    </div>
  );
}

export default BlurImage;

关键注意事项

  • App目录下的页面组件支持直接写成async函数,Next.js会在构建时自动执行数据获取逻辑(默认静态渲染),无需额外配置
  • generateStaticParams仅用于动态路由场景(比如app/products/[id]/page.tsx),返回格式为[{ param1: 'value1' }, ...],用来预生成所有可能的路由路径
  • 始终处理Supabase返回的data可能为null的情况,给默认空数组避免后续map操作报错
  • 补充TypeScript类型定义可以提前发现潜在错误,提升代码健壮性

内容的提问来源于stack exchange,提问作者Wizwoke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 18:14:54