Teraz wrzucimy odpowiedzi do kontekstu, to jest właśnie ta sztuczka z zaawansowanym stanem, jaką chciałem wyrzucić do osobnej lekcji, aby nie przytłaczać materiałem. Zaczynajmy.
Ok, initial state będzie teraz wyglądał tak:
const initialState = {
timedQuestions: false,
timedQuiz: false,
questionTime: 5,
quizTime: 30,
mode: 'menu',
name: '',
score: 0,
answers: []
};
Jak poradzić sobie z takim stanem, typem referencyjnym (obiektem) i zagadnieniem niemutowalności to już ogarnęliśmy, ale samo answers to też obiekt referencyjny (tablica).
Na początku sposób, w jaki robimy ten update może wydać się trudny:
case 'addAnswer': {
return {
...state,
answers: [...state.answers, action.payload]
};
}
Cóż, na to nie ma recepty. Albo to rozumiemy, albo musimy zrozumieć, rozpisać na kartce, albo zrobić 10 takich aplikacji i samo do głowy wejdzie.
Od razu zrobimy restart, aby nam resetował te odpowiedzi:
case 'restart': {
return {
...state,
score: 0,
mode: 'menu',
answers: []
};
}
Ok, teraz quiz będzie wyglądał tak:
function Quiz(){
// const [userAnswers, setUserAnswers] = useState([]);
const [timerKey, setTimerKey] = useState(1);
const {score, name, answers} = useQuiz();
const dispatch = useQuizDispatch();
const activeQuestionIndex = answers.length;
const quizIsComplete = activeQuestionIndex === QUESTIONS.length;
function handleClick(selectedIdx){
console.log(`Selected answer ${selectedIdx}`)
if(selectedIdx === QUESTIONS[activeQuestionIndex].correctIndex){
dispatch({type: 'updateScore', payload: 1});
}
dispatch({type: 'addAnswer', payload: selectedIdx});
setTimerKey((prev) => prev + 1);
}
return (
<>
<p>Your name: {name}</p>
<p>Your score: {score}</p>
{quizIsComplete || <Question timerKey={timerKey} index={activeQuestionIndex} handleAnswer={handleClick} /> }
{quizIsComplete || <SimpleSummary idx={activeQuestionIndex} len={QUESTIONS.length}/>}
{quizIsComplete && <button onClick={() => dispatch({type: "changeMode", payload:"finish"})}>Finish</button>}
</>
)
};
Ogarnijmy wszystko na spokojnie i jak już będziemy mieli pewność, że wiemy obc to ruszamy z następną lekcją, która niedługo!