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

React开发中如何从API返回的数组中仅渲染单条/第一条数据

随机名言功能修复方案

问题根源

你原代码的核心问题是对全量名言数组执行map生成了所有名言的JSX节点,一次性渲染导致内存占用过高崩溃,同时异步逻辑顺序错误导致无法生成有效随机下标:

  • 调用arrayOfQuotes.map会遍历接口返回的1600+条名言全部生成DOM节点,直接存入状态后渲染必然触发内存溢出
  • 异步请求QuoteAPI还没执行完毕时,setIndex(randomIndex(quote))就已经触发,此时quote还是初始空值,无法计算出有效随机下标
  • 不需要把JSX节点存入状态,直接存储原始名言数组即可,渲染时按需取单条数据生成节点更合理

修正后完整代码

import { useState, useEffect } from 'react';
import axios from 'axios';

// 生成有效随机下标
const randomIndex = (arr) => {
  if (!arr || !arr.length) return 0;
  return Math.floor(Math.random() * arr.length);
};

const QuoteCard = () => {
  // 存储全量名言原始数组
  const [quotesArray, setQuotesArray] = useState([]);
  // 存储当前展示的名言下标
  const [currentIndex, setCurrentIndex] = useState(0);

  // 拉取全量名言数组
  const fetchQuotes = async () => {
    try {
      const { data } = await axios.get("https://type.fit/api/quotes");
      setQuotesArray(data);
      // 拿到数组后生成第一个随机下标
      setCurrentIndex(randomIndex(data));
    } catch (err) {
      console.error('名言加载失败', err);
    }
  };

  // 页面初始化仅调用一次接口
  useEffect(() => {
    fetchQuotes();
  }, []);

  // 加载兜底
  if (!quotesArray.length) return <div>加载中...</div>;
  // 仅取出当前要展示的单条名言
  const currentQuote = quotesArray[currentIndex];

  return (
    <div key={currentQuote.id}>
      <h3>{currentQuote.text}</h3>
      <p>{currentQuote.author || '佚名'}</p>
      {/* 可选:新增切换随机名言的按钮 */}
      <button onClick={() => setCurrentIndex(randomIndex(quotesArray))}>
        切换名言
      </button>
    </div>
  );
};

export default QuoteCard;

核心改动说明

  • 调整状态逻辑:只存储原始名言数组,不提前生成全量JSX节点,大幅降低内存占用
  • 修正异步顺序:接口返回全量数组后再生成随机下标,避免空值计算报错
  • 优化渲染逻辑:无需调用map遍历全量数组,直接取下标对应的单条数据渲染即可
  • 补充边界处理:新增加载状态、作者为空时的兜底显示,避免渲染异常

如果你确实需要用map仅渲染第一条数据的特殊场景,可以截取数组第一项后再遍历:arrayOfQuotes.slice(0,1).map(item => /* 渲染逻辑 */),但该场景下直接取单条数据渲染性能更优,无需使用map。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:24:06