在我的代码(React Native)中,为了避免“重新渲染次数过多”错误,我使用了 useEffect 钩子。我希望 useEffect 在组件 PracticeTest 首次运行时运行,但事实并非如此。有人可以解释一下我该如何解决它吗?
function PracticeTest({setCurrentMode}){
const [index, setIndex] = useState(0);
const [selected, setSelected] = useState(0);
const [feedback, setFeedback] = useState('');
const [score, setScore] = useState(0);
// Create 'isCorrect' var to designate if ready to move on to the next question
const [isCorrect, setIsCorrect] = useState(false);
// get only the questions needed
testQuestions = require('./testQuestions.json');
let questionAnswers = [];
let firstQuestionIndex;
let lastQuestionIndex;
let testLength = lastQuestionIndex - firstQuestionIndex;
const [shuffled, setShuffled] = useState(false);
const [done, setDone] = useState(false);
useEffect(() => {
questionAnswers = [];
for(var i=0; i<testQuestions.length; i++){
if((i>=firstQuestionIndex) && (i< lastQuestionIndex)){
questionAnswers.push(testQuestions[i]);
}
}
shuffle(questionAnswers);
testLength = 10;
shuffled = true;
});
// if quizType is "practiceTest" then the questions will be randomly selected and jumbled
// Source for shuffle function (modified by me): https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
function shuffle(array) {
if(shuffled){
console.log("ALREADY SHUFFLEDDDDDDDDDDDDDD");
}
else{
let currentIndex = array.length;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
let randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
console.log("Shuffle!!");
}
}
let question = questionAnswers[index].question;
function check(){
if(selected == questionAnswers[index].correctID){
// add 1 point to score if the feedback is blank
if(feedback==''){
setScore(score+1);
}
setFeedback('Correct!');
setIsCorrect(true);
}
else{
setFeedback("Try again");
}
}
function proceed() {
if((index + 1) >= testLength){
// Code to be executed if done
setDone(true);
}
else{
setIndex(index + 1);
setIsCorrect(false);
setColor1('#FF6868');
setColor2('#FF6868');
setColor3('#FF6868');
setColor4('#FF6868');
setFeedback('');
}
}
const [color1, setColor1] = useState('#FF6868');
const [color2, setColor2] = useState('#FF6868');
const [color3, setColor3] = useState('#FF6868');
const [color4, setColor4] = useState('#FF6868');
return (
<View>
{done ?
<QuizDone setCurrentMode={setCurrentMode} score={score} testLength={testLength}/>
:
<View style={styles.app}>
<Text style={styles.logo}>Testing your Knowledge</Text>
<Text style={styles.question}>{question}</Text>
<AnswerChoices setSelected={setSelected} index={index} questionAnswers={questionAnswers} color1={color1} color2={color2} color3={color3} color4={color4} setColor1={setColor1} setColor2={setColor2} setColor3={setColor3} setColor4={setColor4} />
<BackButton setCurrentMode={setCurrentMode}></BackButton>
{/** Feedback */}
<View style={{
position: 'absolute',
width: 144,
height: 42,
top: 595,
left: 63,
justifyContent: 'center',
}}>
<Text>{feedback}</Text>
</View>
{/** Check Answer */}
{
isCorrect ?
<TouchableOpacity style={styles.checkButton} onPress={proceed}>
<Text style={{color: 'white', alignSelf: 'center',}}>Move on</Text>
</TouchableOpacity>
:
<TouchableOpacity style={styles.checkButton} onPress={check}>
<Text style={{color: 'white', alignSelf: 'center',}}>Check</Text>
</TouchableOpacity>
}
</View>
}
</View>
)
}
我尝试了很多事情,比如添加一个 console.log 来查看 useEffect 是否正在运行,但它没有运行。并且由于 useEffect 内部的代码未运行,因此数组“questionAnswers”没有值。
如果您不使用依赖项数组,则 useEffect 将在每个渲染上运行并且毫无用处。如果您只想在初始渲染时运行效果,则可以提供一个空数组作为依赖项数组: useEffect(() => {...}, [])