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

Next.js中如何将异步API获取的结果列表渲染到组件?

问题解决:异步数据传入Next.js组件的正确方式

核心问题

你直接把getStaticRecycleKPI()的返回值传给了TestGrid的resultList,但async函数的返回值是Promise对象,不是实际的数组。组件里用Array.from(resultList)遍历Promise自然拿不到数据,所以控制台打印不出列表项。

解决方案

针对Next.js项目,有两种标准方案解决异步数据传递问题:

方案一:使用Next.js的getStaticProps(推荐,静态生成场景)

Next.js的getStaticProps会在构建时异步获取数据,然后作为props传给页面组件,这样页面拿到的就是实际的数组,再传给TestGrid即可。

修改index.tsx代码:

import { GetStaticProps } from 'next';
import TestGrid from './path-to-your-testgrid-component'; // 替换成实际组件路径

async function getStaticRecycleKPI() {
  const notion = new Client({
    auth: "....",
  });

  const databaseId = "....";
  const response = await notion.databases.query({
    database_id: databaseId,
  });

  const resultList: REcycleClass[] = [];
  response.results.forEach((employee: any) => {
    resultList.push(
      new REcycleClass(
        employee.properties.Title.title[0].plain_text,
        employee.properties.Number.number,
        employee.properties.Unit.rich_text[0].plain_text
      )
    );
  });

  return resultList;
}

class REcycleClass {
  title: string;
  figure: number;
  unit: string;

  constructor(name: string, amount: number, unit: string) {
    this.title = name;
    this.figure = amount;
    this.unit = unit;
  }
}

// 页面组件,接收getStaticProps返回的数据
export default function Home({ recyclerKPI }) {
  return (
    <section id="recycle_kpi_content">
      <TestGrid
        appliedStyle="gchhkgrid3"
        itemStyle="squaredark"
        resultList={recyclerKPI}
      />
    </section>
  );
}

// 定义getStaticProps,异步获取数据并传给页面
export const getStaticProps: GetStaticProps = async () => {
  const recyclerKPI = await getStaticRecycleKPI();
  return {
    props: {
      recyclerKPI,
    },
    // 可选:设置重新生成时间(秒),用于增量静态再生
    // revalidate: 60,
  };
};

方案二:在页面组件内用useState+useEffect获取数据

如果需要在客户端动态获取数据(比如数据频繁更新),可以在页面组件内用React Hooks处理异步请求:

修改index.tsx的页面组件部分:

import { useState, useEffect } from 'react';
import TestGrid from './path-to-your-testgrid-component';

// ... 保留getStaticRecycleKPI和REcycleClass的定义 ...

export default function Home() {
  const [recyclerKPI, setRecyclerKPI] = useState<REcycleClass[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchData() {
      const data = await getStaticRecycleKPI();
      setRecyclerKPI(data);
      setLoading(false);
    }
    fetchData();
  }, []);

  // 加载状态下可以显示占位符
  if (loading) {
    return <div>加载中...</div>;
  }

  return (
    <section id="recycle_kpi_content">
      <TestGrid
        appliedStyle="gchhkgrid3"
        itemStyle="squaredark"
        resultList={recyclerKPI}
      />
    </section>
  );
}

同步修正TestGrid组件的小问题

  1. React中元素的类名要用className,你代码里的<div class={appliedStyle}>要改成<div className={appliedStyle}>
  2. useEffect要添加依赖项,避免不必要的重复执行;用map替代forEach生成JSX是React常规写法,同时要给列表项加唯一key

修改后的TestGrid组件:

import { useEffect } from 'react';
import Container from '@mui/material/Container';
import Typography from '@mui/material/Typography';
import styles from './your-styles-module.module.css'; // 替换成实际样式路径

const TestGrid = ({ appliedStyle, itemStyle, resultList }) => {
  useEffect(() => {
    console.log(resultList);
  }, [resultList]); // 添加resultList作为依赖,仅数据变化时执行

  const jsx = resultList.map((cardItem, index) => (
    <div className={itemStyle} key={index}>
      <Container className={styles.container_item_1}>
        <Typography variant="h2" color="white" align="center">
          {cardItem.title}
        </Typography>
        {typeof cardItem.figure !== "undefined" &&
          typeof cardItem.unit !== "undefined" && (
            <Typography variant="h2" color="white" align="center">
              {cardItem.figure + " " + cardItem.unit}
            </Typography>
          )}
        <br />
      </Container>
    </div>
  ));

  return <div className={appliedStyle}>{jsx}</div>;
};

export default TestGrid;

说明

  • 方案一适合数据不频繁更新的场景,构建时生成静态页面,性能更好;
  • 方案二适合需要客户端动态获取最新数据的场景;
  • 用map生成JSX时添加key,可以避免React渲染警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:20:32