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

Next.js组件中如何从异步函数获取并渲染summary数组

Next.js异步获取数据并传递给Layout组件的解决方案

原代码存在的问题

  1. 未使用状态管理存储异步获取的summary,组件渲染时无法访问该变量
  2. 直接在组件顶层调用fetchData,会导致每次组件渲染都重复发起请求
  3. 未处理address初始为空的情况,可能导致Campaign初始化失败
  4. 未处理加载、错误状态,用户体验不佳

修改后的完整代码

import { useRouter } from "next/router";
import { useState, useEffect } from "react";
import Layout from '../../components/layout'; // 修正拼写错误:layoyt -> layout
import Campaign from '../../components/campaign';

const Post = () => {
    const router = useRouter();
    const { address } = router.query;
    // 声明状态存储数据、加载状态和错误信息
    const [summary, setSummary] = useState([]);
    const [isLoading, setIsLoading] = useState(true);
    const [error, setError] = useState(null);

    // 用useEffect包裹异步请求,依赖address变化触发
    useEffect(() => {
        if (!address) return; // address为空时不发起请求

        const fetchData = async () => {
            try {
                setIsLoading(true);
                const campaign = Campaign(address);
                const fetchedSummary = await campaign.methods.getSummary().call();
                setSummary(fetchedSummary); // 更新状态存储数据
                setError(null);
            } catch (err) {
                setError(err.message);
                console.error(err);
            } finally {
                setIsLoading(false); // 无论成功失败都结束加载状态
            }
        };

        fetchData();
    }, [address]);

    // 加载状态渲染
    if (isLoading) {
        return <Layout><p>加载中...</p></Layout>;
    }

    // 错误状态渲染
    if (error) {
        return <Layout><p>加载失败:{error}</p></Layout>;
    }

    // 将summary作为props传递给Layout组件
    return (
        <Layout summary={summary}>
            <p>Post : {address}</p>
            {summary.length > 0 && <p>Summary第一个元素:{summary[0]}</p>}
        </Layout>
    )
}

export default Post;

Layout组件接收并渲染summary的示例

// components/layout.js
const Layout = ({ children, summary }) => {
    return (
        <div className="layout">
            <header>页面头部</header>
            <main>
                {children}
                {/* 渲染完整的summary数组 */}
                {summary && summary.length > 0 && (
                    <div className="summary-section">
                        <h3>Summary 数据列表</h3>
                        <ul>
                            {summary.map((item, idx) => (
                                <li key={idx}>第{idx + 1}项:{item}</li>
                            ))}
                        </ul>
                    </div>
                )}
            </main>
            <footer>页面底部</footer>
        </div>
    );
};

export default Layout;

关键修改说明

  • 使用useState声明状态变量存储summary,确保异步数据能被组件捕获并驱动渲染
  • 通过useEffect控制请求时机,仅当address存在且变化时发起请求,避免重复调用
  • 添加加载、错误状态处理,避免页面出现undefined错误,提升用户体验
  • 将summary作为props传递给Layout,使子组件可以直接获取并渲染数组内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:17:51