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

React条件加载提示实现方法及Next.js API数据加载渲染失败解决方案

问题解答

1. 如何在React中创建条件加载消息?

在React里实现条件加载消息,核心思路是用状态管理加载状态,配合条件渲染展示不同内容。具体步骤如下:

  • 用useState声明一个加载状态变量(比如isLoading),初始值设为true
  • 在数据获取逻辑中(比如useEffect或自定义数据钩子),开始请求时把isLoading设为true,请求完成(成功/失败)后切换为false
  • 在组件渲染部分,根据isLoading的值决定显示加载提示还是实际内容

给你一个简单的示例:

import { useState, useEffect } from 'react';

function DataDisplay() {
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [errorMsg, setErrorMsg] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        setIsLoading(true);
        const res = await fetch('你的API地址');
        if (!res.ok) throw new Error('请求失败');
        const result = await res.json();
        setData(result);
      } catch (err) {
        setErrorMsg('加载数据失败,请稍后重试');
      } finally {
        setIsLoading(false); // 无论成功失败,都结束加载状态
      }
    };

    fetchData();
  }, []);

  // 条件渲染逻辑
  if (isLoading) {
    return <div className="loading">加载中,请稍候...</div>;
  }

  if (errorMsg) {
    return <div className="error">{errorMsg}</div>;
  }

  return (
    <div className="content">
      {data?.map(item => (
        <div key={item.id} className="item">
          {item.content}
        </div>
      ))}
    </div>
  );
}

2. Next.js组件等待数据加载完成后渲染的解决方案

先看你的代码,有两个明显的问题会导致渲染失败:

  • 未定义的{title}变量,直接渲染会抛出引用错误
  • 虽然用了getStaticProps(静态生成时在构建阶段获取数据),但如果构建时API请求失败、返回undefined或空数组,直接调用data.map会报错,因为undefined没有map方法

修复后的完整代码:

我给你调整了代码,添加了数据校验、错误处理和空状态展示,确保组件能优雅处理各种情况:

import Head from 'next/head'
import Link from 'next/link'
import Navbar from './Navbar'
import Template from './Template'
import { useState, useEffect } from 'react'

export async function getStaticProps() {
  try {
    const response = await fetch('https://peegin.com/api/public/peegins/recent')
    // 检查请求是否成功
    if (!response.ok) {
      throw new Error(`请求失败,状态码:${response.status}`);
    }
    const data = await response.json()
    return { 
      props: { data },
      // 可选:启用增量静态再生,每60秒后台重新获取数据,保证数据新鲜
      revalidate: 60 
    }
  } catch (error) {
    // 捕获构建时的错误,返回空数据和错误信息,避免页面构建崩溃
    console.error('获取数据失败:', error);
    return { props: { data: [], error: '加载数据失败,请稍后查看' } }
  }
}

const Home = ({ data, error }) => {
  // 处理客户端端的加载状态(比如增量静态再生时的更新)
  const [isClientRefreshing, setIsClientRefreshing] = useState(false);

  // 可选:页面聚焦时重新获取数据(用于客户端数据更新)
  useEffect(() => {
    const refetchData = async () => {
      setIsClientRefreshing(true);
      try {
        const res = await fetch('https://peegin.com/api/public/peegins/recent');
        const newData = await res.json();
        // 这里可以用状态管理更新data,比如用useState
        // setData(newData);
      } catch (err) {
        console.error('客户端重新获取数据失败:', err);
      } finally {
        setIsClientRefreshing(false);
      }
    };

    window.addEventListener('focus', refetchData);
    return () => window.removeEventListener('focus', refetchData);
  }, []);

  // 优先级:先处理客户端刷新状态
  if (isClientRefreshing) {
    return <div>数据更新中...</div>;
  }

  // 处理错误状态
  if (error) {
    return <div className="error">{error}</div>;
  }

  // 处理数据为空的情况
  if (!data || data.length === 0) {
    return <div>暂无最新内容</div>;
  }

  return (
    <div className="content">
      <Head>
        <title>Peegin Recent</title>
      </Head>
      <Navbar />
      {/* 修复title未定义的问题:替换成实际标题,比如下面的示例 */}
      <h2>Latest Peegins</h2>
      {data.map(peegin => (
        <div className="preview" key={peegin.permalink}>
          <h3 className="title">
            {peegin.title}
          </h3>
          <p>{peegin.meaning}</p>
          <p className="example">Example</p>
          <p className="example-content">{peegin.example}</p>
          <p className="origin">Origin: {peegin.origin}</p>
          <div className="name">
            <h4>By</h4>
            &nbsp;
            {/* 用可选链处理user为空的情况,避免报错 */}
            <h4 className="namegreen">{peegin.user?.name || '匿名用户'}</h4>
            &nbsp;
            <h4>{peegin.created_at}</h4>
          </div>
          {/* 用可选链处理views为空的情况 */}
          <p className="views">{peegin.views?.view || 0} Views</p>
        </div>
      ))}
    </div>
  );
}

export default Home;

关键优化说明:

  1. getStaticProps错误捕获:构建时API请求失败不会导致页面崩溃,而是返回错误信息让组件优雅展示。
  2. 多状态判断:依次处理客户端刷新、错误、空数据的情况,避免直接调用map导致的报错。
  3. 可选链操作符(?.):比如peegin.user?.name,防止嵌套属性为空时抛出错误,提升代码健壮性。
  4. 增量静态再生:可选的revalidate配置,让页面后台定期更新数据,保证内容新鲜度。
  5. 修复未定义变量:把未定义的{title}替换成了实际的页面标题,解决引用错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 03:32:44