Home  >  Q&A  >  body text

How can I modify the code to display only 20 random items on refresh, excluding any ordered items?

I asked a question here about how to get 20 random items from this JSON and I used one of the answers below:

const a = Myjson;
  useEffect(() => {
    for (let i = a.length; i-- > 0; ) {
      const j = Math.floor(Math.random() * i); // 0 ≤ j ≤ i
      [a[i], a[j]] = [a[j], a[i]];
    }
  }, []);
    
    {a
      .slice(0, 20)
      .map((item) => (
        <Link
          href={item.ud}
          key={item.id}
        >
         {item.test}
        </Link>
      ))}

There is a problem, when I refresh I see the ordered 20 items of this JSON and then suddenly it changes to a random 20 items; how can I fix the code so that when I refresh I only see the random 20 items and don't see those ordered items?

P粉252116587P粉252116587233 days ago555

reply all(1)I'll reply

  • P粉464088437

    P粉4640884372024-03-23 12:18:13

    You can use useState to provide a consistent (random) ordering that is generated on the first render, instead of using useEffect to update the ordering after the first render:

      const [a] = useState(() => {
        // Same code as in your useEffect, but with `a` renamed for clarity
        let b = [...Myjson];  // take a copy of the array
        for (let i = b.length; i-- > 0; ) {
          const j = Math.floor(Math.random() * i); // 0 ≤ j ≤ i
          [b[i], b[j]] = [b[j], b[i]];
        }
        return b;  // Return value is used as the state value
      });
    
      // ... rendering code as before
    

    useState will run the initialization code the first time the component renders. Although useState also returns a setter, you don't need to use it to retain a specific value between renders if you just want to use it.

    reply
    0
  • Cancelreply