skip to Main Content

I’d like to create a single "Card" component containing some content like title, subtitle, etc picked from a data.js file which contains an array with all these elements. What I want to achive is, it must changes on every refresh giving a different result from the array picked randomly.

For the moment, I could display the single Card element using .map and .slice, but as I said, I’d like to make it changes on every refresh.

Card.js:

import React from "react";
import { curses } from "@/utils/curses";

function Card({ id, curse, russo, trad }) {
  return (
    <div className="flex text-center items-center h-[300px] p-3 bg-card">
      <div className="h-[280px] border-2 border-black p-4">
        <h1 className="font-bold p-4 text-4xl">{curse}</h1>
        <p>Russian: {russo} </p>
        <p>Meaning: {trad} </p>
      </div>
    </div>
  );
}

export default Card;

page.js:

"use client";

import Card from "./components/Card";

import { useEffect, useState } from "react";
import { curses } from "@/utils/curses";

const inter = Inter({ subsets: ["latin"] });

export default function Home() {
  const [data, setData] = useState([]);

  useEffect(() => {
    const loadCurse = curses;
    setData(loadCurse);
  }, []);

  return (
    <main className="flex items-center justify-center h-screen">
      <div>
        {data.slice(0, 1).map((item, id) => {
          return (
            <Card
              key={id}
              curse={item.curse}
              russo={item.russo}
              trad={item.trad}
            />
          );
        })}
      </div>
    </main>
  );
}

data.js:

export const curses = [
  {
    id: "1",
    curse: "Curse 1",
    russo: "",
    trad: "",
  },
  {
    id: "2",
    curse: "Curse 2",
    russo: "XYZ",
    trad: "",
  },
  {
    id: "3",
    curse: "Curse 3",
    russo: "AAA",
    trad: "",
  },
  {
    id: "4",
    curse: "Curse 4",
    russo: "",
    trad: "",
  },
  {
    id: "5",
    curse: "Curse 6",
    russo: "",
    trad: "",
  },
  {
    id: "6",
    curse: "Curse 7",
    russo: "",
    trad: "",
  },
  {
    id: "7",
    curse: "Curse 8",
    russo: "",
    trad: "",
  },
  {
    id: "8",
    curse: "Curse 9",
    russo: "",
    trad: "",
  },
  {
    id: "9",
    curse: "Curse 10",
    russo: "",
    trad: "",
  },
];

How can I achieve this?

2

Answers


  1. I think you can implement this with Math.random() function of javascript

    import { useEffect, useState } from "react";
    import { curses } from "@/utils/curses";
    
        const inter = Inter({ subsets: ["latin"] });
        
        export default function Home() {
          const [data, setData] = useState([]);
          const [index, setIndex] = useState(0);
        
          useEffect(() => {
            const loadCurse = curses;
            const randomIndex = parseInt(loadCurse.length * Math.random());
            setData(loadCurse);
            setIndex(randomIndex)
          }, []);
        
          return (
            <main className="flex items-center justify-center h-screen">
              <div>
                  {data.length > 0 && <Card
                      curse={data[index].curse}
                      russo={data[index].russo}
                      trad={data[index].trad}
                    />}
              </div>
            </main>
          );
    
    }
    
    Login or Signup to reply.
  2. I would do this:

    import Card from "./components/Card";
    
    import { useEffect, useState } from "react";
    import { curses } from "@/utils/curses";
    
    const inter = Inter({ subsets: ["latin"] });
    
    export default function Home() {
      const [data, setData] = useState();
    
      useEffect(() => {
        setData(curses[Math.floor(Math.random() * curses.length)]);
      }, []);
    
      return (
        <main className="flex items-center justify-center h-screen">
          <div>
            {data && (
                <Card
                  key={data.id}
                  curse={data.curse}
                  russo={data.russo}
                  trad={data.trad}
                />
            )}
          </div>
        </main>
      );
    }
    

    EDIT keep in mind if you want to generate another card under any event without refreshing your browser page you can place the code in the effect into that event.

    In case you want to add a button to make the content change:

    import Card from "./components/Card";
    
    import { useEffect, useState } from "react";
    import { curses } from "@/utils/curses";
    
    const inter = Inter({ subsets: ["latin"] });
    
    export default function Home() {
      const [data, setData] = useState();
    
      const generate = () => {
         setData(curses[Math.floor(Math.random() * curses.length)]);
      }
    
      useEffect(() => {
        generate();
      }, []);
    
      return (
        <main className="flex items-center justify-center h-screen">
          <div>
            {data && (
                <Card
                  key={data.id}
                  curse={data.curse}
                  russo={data.russo}
                  trad={data.trad}
                />
            )}
        <button type="button" onClick={() => generate()}>Another</button>
          </div>
        </main>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search