3

I am creating a memory game, i have a shuffle function that shuffles an array of numbers, these numbers are rendered as cards, the problem is that the cards are shuffled every time state changed, i need to only initialize my component with a shuffled array that persists even state is changed!

i tried useEffect, but it doesn't work, or i couldn't implement it correctly

code:

const numbers = [1, 2, 3, 1, 2, 3];

const shuffle = (arr) => {
//shuffle logic here
}

let shuffledCards;
useEffect(() => {
   shuffledCards = shuffle(numbers) // it doesn't help
}, [])

return(
  <cards shuffledCards={shuffledCards} />
)

how can i shuffle my array once instead of every time state is changed!

0

2 Answers 2

4

You can use useMemo hook.

const shuffle = (arr) => {
  //shuffle logic here
}

const shuffledCards = React.useMemo(() => {
  const numbers = [1, 2, 3, 1, 2, 3];  
  return shuffle(numbers);
}, [])

return (
  <cards shuffledCards={shuffledCards} />
)
Sign up to request clarification or add additional context in comments.

3 Comments

at first glance i thought useMemo is a helper from another API, but then realized that it is part of react, thank you
I saw the docs, and it says, "You may rely on useMemo as a performance optimization, not as a semantic guarantee." So, maybe we shouldn't use it? Is it safe?
@Faris hmm guess it’s not safe anymore, especially for this case.
1

Your function is redefining your array shuffleCards each render. If you place the array into state it will be stable.

Define numbers and shuffle outside component as initial state and utility function

const numbers = [1, 2, 3, 1, 2, 3];

const shuffle = array => {
  // shuffle logic
};

Component logic: Initialize state and use the effect to shuffle the array on component mount

const CardShuffler = () => {
  const [shuffledCards] = useState(shuffle(numbers)); // initialize state

  return <Cards shuffledCards={shuffledCards} />;
};

Edit shuffle-cards

4 Comments

thank you, but, i implemented the solution, cards start every time with same numbers, i need when to refresh the page starts with cards with shuffled numbers every time, but not with state change, you can imagine i am creating a memory game!
it worked after i stored that part shuffle(numbers) in a variable and then use it as an argument for setShuffledCards
If you handle the case when shuffledCards = null in <Card /> then this solution also solve your problem.
@CodeEagle It took me a moment to understand what you meant, here's a version that also factors out the shuffle function to be called as an initialization function for useState. At this point though it's nearly pointless to store it in state only to be passed on to Cards, but perhaps you have more logic going on and what you shared here is just a minimal snippet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.