#reactjs #state
Вопрос:
Предыстория: У меня есть приложение для викторины с карточками в react, где у меня есть переменная под названием «Вопросы», которая инициализируется массивом вопросов (которые являются объектами), для каждого из которых изначально установлено свойство длительности 15. Я хочу, чтобы это работало так, что каждый раз, когда пользователь отвечает на вопрос, свойство продолжительности изменяется в зависимости от того, правильно ли был дан ответ на вопрос или нет. И я всегда хочу отображать вопрос, который имеет наибольшую продолжительность.
Вопрос: Проблема в том, что я изменяю продолжительность, но затем она перерисовывается, и продолжительность возвращается к 15. Есть ли способ сохранить его глобальным, но при этом иметь возможность изменять свойства вопроса?
Я знаю, что этот код не является чистым, я просто хочу, чтобы общая структура была удалена.
App.js
function App() {
let questions =[
{
questionText: 'What is the capital of France?',
answerOptions: [
{ answerText: 'New York', isCorrect: false },
{ answerText: 'London', isCorrect: false },
{ answerText: 'Paris', isCorrect: true },
{ answerText: 'Dublin', isCorrect: false },
],
},
{
questionText: 'Who is CEO of Tesla?',
answerOptions: [
{ answerText: 'Jeff Bezos', isCorrect: false },
{ answerText: 'Elon Musk', isCorrect: true },
{ answerText: 'Bill Gates', isCorrect: false },
{ answerText: 'Tony Stark', isCorrect: false },
]
},
{
questionText: 'The iPhone was created by which company?',
answerOptions: [
{ answerText: 'Apple', isCorrect: true },
{ answerText: 'Intel', isCorrect: false },
{ answerText: 'Amazon', isCorrect: false },
{ answerText: 'Microsoft', isCorrect: false },
],
},
{
questionText: 'How many Harry Potter books are there?',
answerOptions: [
{ answerText: '1', isCorrect: false },
{ answerText: '4', isCorrect: false },
{ answerText: '6', isCorrect: false },
{ answerText: '7', isCorrect: true },
],
},
];
const [quizTime, setQuizTime] = useState(90) // in seconds
useEffect(() => {
if (quizTime > 0) {
setTimeout(() => setQuizTime(quizTime - 1), 1000);
return () => clearTimeout(quizTime);
}
});
function checkAnswer(answer, question, time) {
if (answer == null) {
return;
} else {
const longerThanHalf = question.duration - time > question.duration / 2
console.log(time)
if (answer.isCorrect) {
if (longerThanHalf) {
question.duration = question.duration - 2 >= 5 ? question.duration - 2 : 5
} else {
question.duration = question.duration - 1 >= 5? question.duration - 1 : 5
}
}
}
};
const findMaxQuestion = () => {
var max;
questions.forEach( q => {
if (q.duration !== undefined) {
if (max !== undefined amp;amp; q.duration > max.duration) {
max = q
} else max = q
} else {
q['duration'] = 15
if (max !== undefined amp;amp; q.duration > max.duration) {
max = q
} else max = q
}
})
return max
}
if (quizTime > 0) {
let maxQuestion = findMaxQuestion()
console.log(maxQuestion)
return (
<div className="container">
<div>{quizTime} seconds left</div>
<FlashCard question = {maxQuestion} checkAnswer = {checkAnswer}/>
</div>
);
}
}
Ответ №1:
Попробуй вот это. setInterval будет обновлять ваше состояние каждые 1000 мс. Замените свой эффект использования этим.
useEffect(() => {
if (quizTime > 0) {
const time = setInterval(() => setQuizTime(quizTime - 1), 1000);
return () => clearInterval(time);
}
}, []);