Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display Only 3 Objects at the time

I have a quote generator that I am trying to implement a feature of displaying a specific amount of objects at the time. I have tried using map, but it returns that it's not a function. Right now I have it to generate a random quote, but I want to have the option to display a specific number. Any help is greatly appreciated. the is what is working, but I commented out to try out the 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 [quote, setQuote] = useState();
  const [isLoading, setIsLoading] = useState(true);
  const randomise = () => {
    const randomNumber = Math.floor(Math.random() * data.length);
    setQuote(data[randomNumber]);
  };
  //math.floor makes it a whole number, and the equation above goes through the data at random
  useEffect(() => {
    randomise();
    setIsLoading(false);
  }, []);

  return (
    <div className="App">
      <Header />
      <div className="main">

      <h1>Quote Generator</h1>
      {isLoading ? <p>Quote now loading...</p> : <Quote data={quote} />}
      <button onClick={randomise}>Generate Quote</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.slice(0).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>

))}



</div>

            {/* <blockquote> {
                data.quote
            }
                <p>-{
                    data.name
                }</p>
            </blockquote> */}



        </div>

    )
}

export default Quote;
like image 807
CodingNewb Avatar asked Dec 21 '25 16:12

CodingNewb


1 Answers

Here's what you can do:

  1. Use an array for the quote state
  2. Randomize by:
    • Cloning the quote array -> tempData = [...data]
    • Create an array to hold the quotes to be set -> tempQuotes
    • Iterate for the number of quotes you need and:
      • splice() a quote out of tempQuotes using the randome index
      • push it into tempQuotes
        • Spread ... because splice returns an array
      • Iterate again with the remaining quotes in tempData
  3. Set the new quote state
  4. Map and render

Code Sandbox

import { useState, useEffect } from "react";

const data = [
  "Another one bites the dust",
  "Sweet dreams are made of this",
  "Never gonna give you up",
  "Highway to the danger zone",
  "Let the bodies hit the floor",
  "Hey now, I'm an allstar",
  "Hello darkness my old friend"
];

function App() {
  const [quotes, setQuotes] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const numberOfQuotes = 3;

  const randomise = () => {
    const tempData = [...data];
    const tempQuotes = [];
    for (let i = 0; i < numberOfQuotes; i++) {
      const randomNumber = Math.floor(Math.random() * tempData.length);
      tempQuotes.push(...tempData.splice(randomNumber, 1));
    }
    setQuotes(tempQuotes);
  };
  
  useEffect(() => {
    randomise();
    setIsLoading(false);
  }, []);

  const quoteEls = quotes.map((quote) => <li class="quote">{quote}</li>);

  return (
    <div className="App">
      <div className="main">
        <h1>Quote Generator</h1>
        {isLoading ? <p>Quote now loading...</p> : quoteEls}
        <button onClick={randomise}>Generate Quote</button>
      </div>
    </div>
  );
}

export default App;

If data is large and you don't want to clone it to memory each time, you can:

  1. Make an array of indices i.e. [0,1,2,3] using Array.from()
  2. Randomly splice indices out of it like we did above
  3. map that array to your data

The function below is just for demonstration, but it'll be easy to integrate into your code if decide to do so.

const data = [
  "Another one bites the dust",
  "Sweet dreams are made of this",
  "Never gonna give you up",
  "Highway to the danger zone",
  "Let the bodies hit the floor",
  "Hey now, I'm an allstar",
  "Hello darkness my old friend"
];

const numberOfQuotes = 3

function randomize() {
  const quoteIndices = []
  const indices = Array.from({length: data.length}, (a,i) => i) // Make array of indices
  for (let i = 0; i < numberOfQuotes; i++){
    let randomNumber = Math.floor(Math.random() * indices.length);
    quoteIndices.push(...indices.splice(randomNumber, 1))
  }
  return quoteIndices.map(index => data[index])
}

console.log(randomize())
like image 155
Brother58697 Avatar answered Dec 23 '25 05:12

Brother58697