0

I'm doing a project in React, and on my "Home.js" page I would like to display a pokemon randomly for 24 hours thanks to the PokeApi (https://pokeapi.co/). But I can't add the fact that the Pokemon image should be displayed for 24 hours.

For now I have already tried this, it displays an image but it changes when you refresh the page.

Here is my line of code so far:

Home.js :

<div className="rightPane">
        {dataPkmn && dataSpecies ? <PokemonDuJour id={Math.floor(Math.random() * (898 - 1)) + 1} /> : <div></div>}
        </div>

Can you help me please to know what should I add in my code? thank you in advance for your help

PokemonDuJour.js

const PokemonDuJour = (props) => {

    const param = useParams()

    const [pkmnId, setPkmnId] = useState();
    const [img, setImg] = useState(String);
    const [name, setName] = useState(String);
    const [type1, setType1] = useState("");
    const [type2, setType2] = useState("");
    const [data, setData] = useState();
    const [species, setSpecies] = useState();

    //REDUX
    const dataPkmn = useSelector((state) => state.dataPkmn.pkmn)
    const dataSpecies = useSelector((state) => state.dataPkmn.species)

    const navigate = useNavigate();

    const handleClick = () => {
        if (pkmnId) {
            setType1("")
            setType2("")
            navigate("/pokemon/" + pkmnId);

        }
    }

    useEffect(() => {
        if (data && species) {
            if (data.sprites.other.dream_world.front_default != null) {
                setImg(data.sprites.other.dream_world.front_default)
            } else if (data.sprites.other.home.front_default != null) {
                setImg(data.sprites.other.home.front_default)
            }
            setType1(data.types[0].type.name)
            if (data.types.length > 1) {
                setType2(data.types[1].type.name)
            }
            setPkmnId(data.id)

            species.names.forEach(element => {
                if (element.language.name == "fr") {
                    setName(element.name)
                }
            });
        }
    }, [data && species]);
    useEffect(() => {
        if (dataPkmn) {
            setData(dataPkmn.payload[props.id - 1])
        }
    }, [dataPkmn && param])

    useEffect(() => {
        if (dataSpecies) {
            setSpecies(dataSpecies.payload[props.id - 1])
        }
    }, [dataSpecies && param]);

    return (
        <div className='card' >
            {
                data ?
                    <div className="pkmnDuJour" onClick={handleClick}>
                        <p className='pkmnName'>{name}</p>
                        <img src={img} alt="pkmnImage" className='pkmnImage' />
                        
                    </div>
                    :
                    <div></div>
            }

        </div>
    );
};

export default PokemonDuJour;

stosto
  • 17
  • 6
  • Instead of generating a (pseudo-) **random** index for your pokemon ID, you should generate a (seemingly random, but) **deterministic** ID based on a date value that only changes every 24 hours (e.g. [ordinal date](https://en.wikipedia.org/wiki/Ordinal_date)). – jsejcksn May 10 '22 at 21:28
  • How I do this ? – stosto May 11 '22 at 20:03
  • @stosto: Any sort of algorithm or mapping would be up to you, really. Effectively you just want to create some way to convert a current date (day of month? day of month + month of year? day of month + month of year + year? something else?) to an identifier for the record you want (what are their identifiers and how many are there?). For example, if there were 366 pokemon then you could map the identifier from the current day of the year. The point is that the mapping is up to you, based on logic you define. – David May 11 '22 at 20:19

1 Answers1

1

Following up on my comment: You need to generate a deterministic ID based on the current date, but it needs to be one that seems "random". This problem could be solved a number of ways, but here's one:

  1. Generate shuffled array of pokemon IDs and include the array as a constant in your source code. The following snippet demonstrates how you could do that. Copy the array value and paste it into your JavaScript module source code, saving it with a variable name (e.g. pokemonIds). You will refer to this shuffled array in the next part.

/**
 * Durstenfeld shuffle
 *
 * - https://stackoverflow.com/a/12646864/438273
 * - https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
 */
function shuffleArray (array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
}

/** Get shuffled array of all pokemon ID values */
function generateShuffledIntegerArray (minId = 1, maxId = 898) {
  const arr = [];
  for (let i = minId; i <= maxId; i += 1) arr.push(i);
  shuffleArray(arr);
  return arr;
}

const arrayString = `[${generateShuffledIntegerArray().join()}]`;
console.log(arrayString);
  1. Create a function to get the current UNIX time, rounded to the nearest 24 hours (so the value only changes once per day). Get the remainder (%) of dividing this value by the length of the array and use it as the index of the pokemon ID in your shuffled array:

// Generated using the code snippet above
const pokemonIds = [162,606,843,194,531,39,838,805,724,251,389,607,510,216,60,582,407,501,633,787,594,643,569,654,898,352,131,62,611,296,536,209,223,747,857,850,622,468,530,615,563,855,733,831,25,825,47,49,791,758,889,703,823,134,708,885,390,41,335,782,232,23,711,219,112,494,839,301,137,298,449,380,507,752,329,382,413,650,276,846,120,114,421,726,43,844,757,590,532,29,269,357,580,612,206,544,671,398,445,300,203,877,763,619,124,211,684,262,801,321,789,682,235,858,107,481,437,244,369,362,133,756,283,515,422,736,602,217,322,388,240,285,381,521,534,65,852,5,154,226,803,879,784,99,585,70,834,161,54,813,778,833,238,141,538,878,490,578,175,201,666,753,564,340,184,553,699,28,632,26,652,663,159,312,727,370,355,754,687,106,555,780,20,762,404,722,659,816,197,234,372,125,854,147,158,830,4,812,80,500,662,136,228,279,886,432,700,373,185,819,341,503,31,718,755,571,874,749,19,851,97,866,497,828,69,315,853,444,239,396,759,333,795,868,512,760,42,263,331,212,170,204,483,799,796,48,627,550,172,243,319,339,664,363,377,892,145,132,344,230,284,596,587,470,246,53,526,751,802,386,384,548,584,186,875,655,770,567,143,516,156,392,405,408,277,744,463,96,642,807,220,668,21,731,785,295,395,489,638,440,214,476,741,109,842,361,88,236,527,566,371,702,560,151,628,306,139,737,359,613,410,416,222,271,393,609,104,412,809,518,788,215,100,64,871,127,163,168,356,691,576,677,208,672,83,589,641,509,504,426,304,248,10,310,237,617,196,523,255,734,451,14,385,366,221,506,768,130,270,378,292,869,568,498,767,78,701,375,231,661,565,425,583,690,790,367,191,495,146,631,595,640,742,334,732,837,797,287,535,126,697,719,174,520,150,525,79,660,896,717,265,715,311,713,696,402,658,774,278,513,880,273,895,561,349,639,674,195,884,452,679,188,102,709,116,9,8,115,695,456,85,436,111,336,63,427,233,129,496,157,250,179,505,511,461,293,180,556,327,781,465,66,862,685,294,258,6,33,282,218,91,18,457,182,267,61,673,95,118,178,169,32,841,818,771,716,829,346,330,469,207,519,433,488,680,675,665,318,17,804,397,324,419,459,579,289,810,345,669,314,144,365,776,840,723,455,623,524,453,775,546,434,247,558,689,450,332,464,36,24,592,108,646,888,730,411,547,849,160,37,400,40,867,777,424,681,342,45,478,2,574,438,189,368,280,460,769,491,82,58,379,348,52,119,766,575,274,467,229,140,442,735,577,537,290,176,94,714,887,305,149,173,401,486,599,845,123,430,783,38,51,891,227,872,46,68,637,484,299,861,761,856,588,794,148,740,748,479,364,103,268,806,573,881,224,15,257,473,353,343,30,541,826,676,254,821,308,286,625,720,694,199,647,811,559,171,529,634,616,543,600,260,266,259,87,153,22,193,865,443,439,338,683,420,746,34,832,92,897,636,187,551,272,16,514,399,656,317,387,621,487,275,545,350,706,793,13,779,528,698,549,376,121,200,192,447,73,138,798,3,76,190,454,883,431,326,374,383,164,135,93,428,113,316,210,738,429,792,406,773,166,707,827,474,323,605,894,435,458,570,678,522,105,648,835,705,822,302,466,848,598,264,750,418,693,824,499,502,630,86,876,739,472,645,1,122,552,181,554,462,213,205,591,604,764,183,540,603,629,253,586,864,800,252,415,7,743,686,626,508,423,601,814,245,728,27,337,110,256,542,539,142,651,288,836,860,72,729,492,725,409,77,320,657,56,152,557,313,57,441,167,351,635,670,482,328,624,241,893,417,261,870,480,710,808,815,572,890,81,249,446,471,517,414,644,786,562,688,202,745,155,394,820,653,485,11,360,44,391,712,90,649,325,71,354,165,608,817,593,847,475,403,177,67,225,721,101,309,704,89,35,859,448,12,581,75,765,55,873,597,297,882,620,347,667,84,358,198,242,493,610,477,117,291,618,50,533,614,863,128,74,98,281,303,307,692,772,59];

/** Get UNIX date value, rounded to nearest 24 hours */
function getUnixDate (date = new Date()) {
  const DAY = 1000 * 60 * 60 * 24;
  return Math.floor(date.getTime() / DAY);
}


function getDailyPokemonId (date = new Date()) {
  const day = getUnixDate(date);
  const index = day % pokemonIds.length;
  return pokemonIds[index];
}

const id = getDailyPokemonId();
console.log(id);

Then, simply use it like this to get a "random" pokemon each day (but the ID will only change once per day):

<PokemonDuJour id={getDailyPokemonId()} />
jsejcksn
  • 27,667
  • 4
  • 38
  • 62
  • Thanks ! I Where can I write this? :0 I have edited my post to add my PokemonDuJour.js file – stosto May 12 '22 at 20:46
  • @stosto It doesn't really matter: you can export it from any module as long as you import it where you need to use it. If you're using it in `home.js`, then you don't need to export it, you can just put it in that module and use it there. – jsejcksn May 12 '22 at 23:27