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

React名言生成器:实现单次显示指定数量对象功能求助

React名言生成器:实现指定数量名言显示功能的解决方案

我开发了一个React名言生成器,想要实现单次显示指定数量名言对象的功能。尝试使用map函数时出现“不是函数”的报错,当前仅能生成随机单条名言,希望添加显示指定数量的选项。

错误原因

当前quote状态存储的是单个名言对象(data[randomNumber]返回数组中的某一项),而map是数组专属方法,直接对单个对象调用map必然触发“不是函数”的错误。要实现多条显示,需将状态改为存储名言数组,同时调整生成逻辑。

修改方案

1. 调整状态与生成逻辑

  • 将quote状态改为数组类型,用于存储多条名言
  • 新增quoteCount状态控制显示数量
  • 重写randomise函数,生成指定数量的随机名言(支持不重复)

2. 更新组件渲染逻辑

  • 给Quote组件传递数组类型的data
  • 确保Quote组件正确处理数组的map渲染

修改后的完整代码

App.js

import { useState, useEffect } from "react";
import Footer from "./Components/Footer/Footer";
import Quote from "./Components/Quote/Quote";
import "./App.css"
import { data } from "./Components/Data/Data";
import { characterData } from "./Components/Data/CharacterData"
import CharacterBios from "./Components/CharacterBios/CharacterBios";
import Header from "./Components/Header/Header";

function App() {
  const [quotes, setQuotes] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [quoteCount, setQuoteCount] = useState(1);

  // 生成指定数量的不重复随机名言
  const randomise = () => {
    const selectedQuotes = [];
    const count = Math.min(quoteCount, data.length);
    const dataCopy = [...data];
    
    for (let i = 0; i < count; i++) {
      const randomIndex = Math.floor(Math.random() * dataCopy.length);
      selectedQuotes.push(dataCopy.splice(randomIndex, 1)[0]);
    }
    setQuotes(selectedQuotes);
  };

  useEffect(() => {
    randomise();
    setIsLoading(false);
  }, []);

  return (
    <div className="App">
      <Header />
      <div className="main">
        <h1>Quote Generator</h1>
        {/* 添加数量选择控件 */}
        <div style={{marginBottom: '1rem'}}>
          <label>显示数量:</label>
          <select 
            value={quoteCount} 
            onChange={(e) => setQuoteCount(Number(e.target.value))}
          >
            {[1,2,3,4,5].map(num => (
              <option key={num} value={num}>{num}条</option>
            ))}
          </select>
        </div>
        {isLoading ? <p>Quote now loading...</p> : <Quote data={quotes} />}
        <button onClick={randomise}>生成名言</button>
        <CharacterBios characterData={characterData} />
        <Footer />
      </div>
    </div>
  );
}

export default App;

Quote.jsx

import React from 'react'

const Quote = ({data}) => {
    return (
        <div className='container quote-section'>
            <div className="row">
                {data.length > 0 ? data.map((item, index) => (
                    <div className="col-xl-4 col-lg-4 col-md-6 col-sm-12" key={index}> 
                        <div className="marked-content-card">
                            <p><span className="name">{item.name}</span></p>
                            <p>{item.quote}</p>
                        </div>
                    </div>
                )) : <p>暂无名言</p>}
            </div>
        </div>
    )
}

export default Quote;

可选优化

  • 如果允许重复名言,可以简化randomise函数:直接循环quoteCount次,每次随机取data中的一项加入数组
  • 数量选择控件可换成输入框,添加数值校验(比如不能小于1、不能超过总名言数)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 00:15:59