Ron Nielsen
Ron Nielsen

Reputation: 35

React Hooks: Shuffle array immediately on load, and onClick

I have an array that I am trying to shuffle on initial load, and onClick. My functions seem to be working but aren't visible unless there is a page rerender.

2 issues I'm trying to resolve:

  1. I want to shuffle on initial load, but the shuffle doesn't occur unless there is a rerender.

  2. I want to shuffle on button press, but the shuffle doesn't occur unless there is a rerender.

Here is my CodeSandbox

Thanks

import React, {
  useEffect,
  useState
} from "react";

const myArray = [{
    name: "cat",
    count: 0
  },
  {
    name: "dog",
    count: 0
  },
  {
    name: "hamster",
    count: 0
  },
  {
    name: "lizard",
    count: 0
  }
];

function shuffle(arra1) {
  var ctr = arra1.length,
    temp,
    index;
  while (ctr > 0) {
    index = Math.floor(Math.random() * ctr);
    ctr--;
    temp = arra1[ctr];
    arra1[ctr] = arra1[index];
    arra1[index] = temp;
  }
  return arra1;
}

function App(props) {
  const [list, setList] = useState(myArray);
  useEffect(() => {
    const mountArray = shuffle(myArray);
    setList(mountArray);
  }, []);

  function handleShuffle() {
    const changes = shuffle([...list]);
    setList(changes);
    console.log("Shuffle", myArray, changes);
  }

  return ( 
  <div> 
    {list.map((x, index) => ( 
      <div key = {x.name + x.index}> 
        {x.name} - {x.count} 
        <button onClick={() => setList([...list], (x.count = x.count + 1))}>
        +
        </button> 
      </div>
    ))} 
    <button onClick={handleShuffle}>
      Shuffle 
    </button>
  </div>
  );
}

export default App;

Upvotes: 3

Views: 2425

Answers (3)

ikmo
ikmo

Reputation: 298

HAI i have made some changes in App.js

  import React, { useEffect, useState } from "react";

const myArray = [
  { name: "cat", count: 0 },
  { name: "dog", count: 0 },
  { name: "hamster", count: 0 },
  { name: "lizard", count: 0 }
];

function shuffle(arra1) {
  var ctr = arra1.length,
    temp,
    index;
  while (ctr > 0) {
    index = Math.floor(Math.random() * ctr);
    ctr--;
    temp = arra1[ctr];
    arra1[ctr] = arra1[index];
    arra1[index] = temp;
  }
  return arra1;
}

function App(props) {
  const [list, setList] = useState(myArray);
  useEffect(() => {
    const mountArray = shuffle(myArray);
    setList(mountArray);
  }, []);

  function handleShuffle() {
    const changes = shuffle([...list]);
    setList(changes);
    console.log("Shuffle", myArray);
  }

  return (
    <div>
      {list.map((x, index) => (
        <div key={x.name + x.index}>
          {x.name} - {x.count}
          <button onClick={() => setList([...list], (x.count = x.count + 1))}>
            +
          </button>
        </div>
      ))}
      <button onClick={handleShuffle}>Shuffle</button>
    </div>
  );
}

export default App;

Upvotes: 3

DedaDev
DedaDev

Reputation: 5249

Html changes only if the state has changed, so make some state inside a component, and update it every time you want to update the html.

function App(props){
    const [myArray, setMyArray] = useState([])

    // rest of the code
}

Upvotes: -2

EugenSunic
EugenSunic

Reputation: 13703

Your setList function is used to modify the array and returns a new array, with shuffled values, so you need to apply that function non initial rendering.

 useEffect(() => {
    setList(shuffle(myArray))     
  }, []);

Upvotes: 1

Related Questions