I'm trying to make an app where the user can cycle through a pack of cards. I'm trying to make it so each card is unique so that a user cannot pick two of the same card consecutively. Therefore the way I thought of doing this was by adding all the cards to an array and then shuffling that array.
import * as React from "react";
import { View, Text, Button } from "react-native";
import homeStyles from "../styles/homeStyles";
import { cardsList } from "../assets/cardsList";
import { useEffect, useState } from "react";
export default function Home() {
const [CurrentQuestion, setCurrentQuestion] = useState(1);
const [usedQuestions, setUsedQuestions] = useState([]);
const test = [];
const length = cardsList.length;
const shuffle = () => {
let i,
x = 0,
y = 0,
temp0 = 0;
for (i = 0; i < usedQuestions.length; i ) {
x = Math.floor(Math.random() * usedQuestions.length);
y = Math.floor(Math.random() * usedQuestions.length);
if (x === y) {
//for dont change arr[index] with self !!!
continue;
}
temp0 = usedQuestions[x];
usedQuestions[x] = usedQuestions[y];
usedQuestions[y] = temp0;
}
console.log("Shuffled : " usedQuestions);
};
let i = 0;
const nextQuestion = () => {
let plz = null;
if (i <= usedQuestions.length) {
// plz = usedQuestions[i]
setCurrentQuestion(usedQuestions[i]);
i = i 1;
} else {
i = 0;
// shuffle()
// nextQuestion()
}
// console.log(plz)
console.log(CurrentQuestion);
};
const start = () => {
let i = 1;
while (i <= length) {
test.push(i);
i ;
}
console.log("initial : " test);
setUsedQuestions([...usedQuestions, ...test]);
};
return (
<View style={homeStyles.container}>
<View style={homeStyles.card}>
{cardsList
.filter(function (item) {
return item.id === CurrentQuestion;
})
.map((cardsList) => {
return (
<View key={cardsList.id}>
<View style={homeStyles.line}>
<Text style={homeStyles.cardNumber}>
{cardsList.id}) {cardsList.title}
</Text>
</View>
<Text style={homeStyles.cardText}>{cardsList.cardText}</Text>
</View>
);
})}
<Button
style={homeStyles.button}
title="Shuffle"
onPress={() => shuffle()}
/>
<Button
style={homeStyles.button}
title="Next Question"
onPress={() => nextQuestion()}
/>
<Button
id="test"
style={homeStyles.button}
title="Start"
onPress={() => start()}
/>
</View>
</View>
);
}
The section below is the section causing me issues
let i = 0;
const nextQuestion = () => {
let plz = null;
if (i <= usedQuestions.length) {
// plz = usedQuestions[i]
setCurrentQuestion(usedQuestions[i]);
i = i 1;
} else {
i = 0;
// shuffle()
// nextQuestion()
}
// console.log(plz)
console.log(CurrentQuestion);
};
The const plz works perfectly returning the value of the cards one by one from the shuffled array. See Image
However when I try and use the UseState feature from react to set this value so that I can use it to display the correct part in the app section it breaks.
Any idea why this happens and how I can fix it? I'm fairly new to coding so any tips on how I could better it would be appreactiated.
CodePudding user response:
You cannot modify a state directly
You can create a copy, shuffle it and reassign the state in this way
const shuffle = () => {
setUsedQuestion(u => {
const data = [...u]
data.sort(() => Math.random() - 0.5))
console.log("Shuffled : " data);
return data;
}
)
}
CodePudding user response:
Everytime you update a react state (eg. by calling setCurrentQuestion) your component will rerender.
Here, rerendering means it will execute the code of your function component again (function Home()
).
In the body of function Home()
you have this: let i = 0;
so i
will reset everytime you change a local state.
Now what you probably want is to persist the current question index across multiple rerenders.
you could do nextQuestion
like this:
// remove: const [CurrentQuestion, setCurrentQuestion] = useState(1);
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
const currentQuestion = usedQuestions[currentQuestionIndex];
const nextQuestion = () => {
if (currentQuestionIndex < usedQuestions.length) {
setCurrentQuestionIndex(currentQuestionIndex 1);
} else {
setCurrentQuestionIndex(0);
}
};
You might have more tweaking to do but that should get you started