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
相关产品推荐
相关产品推荐

