자 이제 잘 작동하는 타이머가 있으니
사용자가 답을 선택하면
해당 답변을 강조 표시함으로써
더 나은 앱으로 만들어 보겠습니다
그리고 몇 초 뒤
답변이 올바르면
초록색으로
그리고 틀리면 빨간색으로
바뀌도록 하고 약 2초 뒤
다음 질문이 로딩 되도록 하겠습니다
답변이 선택될 때마다
바로 바뀌게 하는 대신
답변이 올바른지 혹은 틀렸는지를 유저에게
보여주고 싶습니다
다음 문제로 넘어가기 전의 시점입니다
이 부분을 작업하겠습니다
이것을 적용하기 위해선
코드 내 몇 가지 변경 사항이 요구됩니다
정확하게 말하자면
Quiz 컴포넌트에서
여기 이 handleSelectAnswer 함수를
이용할 겁니다
선택된 답변을 바로 보관하기보다
다음 문제로
이어지게 하는 작업입니다
넘어가기 전에 선택된 답변의
색상을 바꾸고 싶습니다
그러기 위해선 두 번째 상태를
작업하겠습니다
그리고 이는 currentAnswerState를 제어합니다
그리고 이는 아직 텅 빈 문자열입니다
예를 들어, '답변하지 않음'와 같은 텍스트를
추가하자면 이는 질문에
답을 아직 선택하지 않았다는 의미인데
텅 빈 문자역에 가서
이것을 answer 상태로 명명할 겁니다
그리고 setAnswerState 업데이트 함수를 추가합니다
그리고 여기 handleSelectAnswer에서
answerState를 변경하고 싶습니다
'답변 완료'로 바꾸는 것입니다
사용자가 답변을 고른다면
set timeout을 이용해서 타이머를 설정할 겁니다
그래서 1초 뒤에
즉 1000밀리초 뒤에
만약 올바른 답이 선택된다면
answerState를 correct로
틀린 답이 설정된다면 wrong으로 하겠습니다
그리고 해당 상태를 이용하여
답변의 형식을 업데이트 하겠습니다
그래서 여기 1초 뒤에
맞는 답변인지 틀린 답변인지 일단
알아보고 싶습니다
그걸 위해선
if check를 추가합니다
그리고 사용자가 선택한
답안을 확인합니다
바로 selectedAnswer이죠
그리고 이전에 표시됐던
질문의 올바른 답과 비교합니다
그리고 우리는
모든 질문의 답에 관해서
첫 번째 답변이 정답이라는 것을 압니다
여기 미처리 데이터에서는 첫 번째가 정답입니다
그래서 만일 selectedAnswer이 첫 번째 답과 같다면
정답이 선택되었다는 것을 알 수있습니다
그래서 우리는
selectedAnswer이 Questions과 같은지 확인합니다
미처리 QUESTIONS 데이터에도 비교해보고
그리고 activeQuestionIndex에도 비교합니다
그러고 나서
답변 목록에서 첫 번째 답안을 보면 됩니다
만일 selectedAnswer이
첫 번째 답안과 같다면
선택된 답안이 정답이라는 것을 알 수 있고
상태를 업데이트하고
여기 처럼 setAnswerState를 correct로 설정하면 됩니다
그게 아니면, answerState를 wrong으로 설정합니다
이는 오답을 골랐을 경우입니다
그렇게 해서
handleSelectAnswer 함수 안에서
activeQuestionIndex를 사용하고 있습니다
그리고 이것이 useCallback으로 감싸져 있기에
useCallback의 의존성 배열에
activeQuestionIndex를 추가해야 합니다
왜냐하면 useCallback에 의해
감싸진 함수는 activeQuestionIndex value 값이 변경될 때마다
재생성 되어야 하기 때문 입니다
해당 함수 안의 값을 사용하고
최신 상태가 아닌 값를 사용하기를 원치 않기 때문입니다
이것은 중요한 부분입니다
여기 answerIndex가 변경될 때마다 재생성되어야만 합니다
그러므로 의존성으로 추가되어야 하는 겁니다
이제
새로운 문제가 생깁니다
activeQuestionIndex가
사용자가 답변을 선택하면
바뀐다는 문제입니다
한 가지 해결 방법은
userAnswers 배열을 업데이트하는 이 코드를
이 timeout에 옮기는 겁니다
이는 답변이 정답인지 오답인지 기록하는 위치입니다
그런데 이렇게 하면
아직 오답인지 정답인지 알자마자
해당 질문으로부터 다음 질문으로
바로 넘어간다는 것입니다
그리고 바로 넘어가기 때문에
사용자에게 정답인지 오답인지 보여주는
이 형식을
업데이트 할 수 없게 됩니다
대신에 사용할 방법은
여기로 돌아와서
activeQuestionIndex가 userAnswers 길이와
같도록 하고
만일 currentAnswerState가 텅 빈 문자열이라면
이는 질문의 답변이 아직 정해지지 않았을 때입니다
그래서 텅 빈 문자열이라면
currentActiveQuestionsIndex는
userAnswers 길이와 같습니다
아니라면 userAnswers - 1의 값과
같아야 합니다
그래서 아직 이전 질문에 머무르도록 합니다
그리고 이는answerState를
결과적으로 빈 문자열로
초기화해야 한다는 뜻이기도 합니다
그리고 이곳에서 답변이 정답인지 오답인지 정해지면
초기화해야 합니다
여기에 새로운 타이머를 설정해줍니다
그래서 여기에 끼워 넣은 타이머가 있습니다
이 타이머가 만료된 후에 시작할 타이머입니다
이 타이머는 이제 2초로 선택 될 겁니다
그리고 여기에 answerState를
텅 빈 문자열로 다시 설정합니다
끝 부분에서 답변이 초기화 되도록 해야 하기 때문입니다
말하자면
정답이나 오답으로 더 이상 표시되지 않도록 하는 것입니다
그리고 여기에 추가한 로직 때문에
여기서는 다음 질문으로 넘어가게 됩니다
그래서 제대로 잘 작동하는지 한 번 보겠습니다
보기 위해선
여기 이 컴포넌트의
형식을 조금 업데이트 하도록 하겠습니다
answerState를 기반으로 하겠습니다
그걸 위해
여기 버튼으로 가서
그리고 className을 추가합니다
그리고 이를 동적 값으로 설정합니다
그리고 이 className은 텅 빈 문자열일 겁니다
만약 답변이 아직 선택되지 않은 경우입니다
선택되었다고 한다면
여기서는 선택되었다고 해봅시다
그리고 올바르게 선택 되었다면 correct
틀리게 선택 되었다면 wrong이 됩니다
그러므로 여기 목록에서
map으로 전달한
이 함수를 확장시키겠습니다
이걸 잘라내고 이 목록 항목을 반환하고
그리고 CSS 클래스를 파생합니다
cssClass는 이 버튼에 추가되어야 하죠
그렇게 하면 cssClasses 변수을 가질 수 있게 됩니다
그리고 이는값으로 사용되어야 합니다
그리고 이제 cssClasses는 해당 답변이
선택되었는지 아닌지,
선택되었다면 정답인지 오답인지에 따라 변경될 겁니다
그래서 여기에서 answerState가 '답변 완료' 즉 Answered인지
확인하고 싶습니다
이는 우리가 설정하고자 하는
상태값입니다
만일 그 경우라면
또한 그것이 여기에 선택되어
출력되고 있는 특정한 답변인지
아닌 지에 대해 알아보고 싶습니다
왜냐하면 답변의 목록을 출력할 때
그들 중 하나만 선택될 것이기 때문입니다
그리고 우리는
이 답변이 선택된 것인지를 알 수 있습니다
바로 사용자의 답변을
보는 것으로 가능합니다
그 이유는 답변이 선택되자마자
업데이트 하고 있기 때문입니다
어떤 정답을 골랐는지 알아보기 위해
마지막 요소를 들여다 볼 수 도 있습니다
그래서 여기 도움을 줄 만한 것을 추가해보겠습니다
상수값이고 isSelected로 명명하겠습니다
그리고 여기에서 userAnswers를 넣습니다
그리고 마지막 요소로서
userAnswerslength - 1을 넣어줍니다
여기에는 users가 아니라 useranswer이 필요합니다
그리고 이것이 이 answer과 같은지 확인을 합니다
이는 현재 출력하고 있는 값입니다
그 경우라면
이 답변이 선택된 답변이란 것을 알 수 있습니다
그러니 아래에 isSelected를 사용합니다
그러면 answerState가 답변 완료되었다는 것을 알 수 있습니다
그리고 이 answer가 선택되었다는 것을 알 수 있습니다
그래서 이 경우
여기에 적용하고 싶은 cssClass는 selected입니다
그리고 selected가 되어야 하는 이유는
이는 인덱스 파일(Index.css)에 제가 준비해둔
클래스들 중 하나기 때문입니다
그리고 이를 저 아래에 cssClass라고 이름을 바꿉니다
그렇게 해서
선택되고 있는 것처럼 업데이트 하고 있습니다
이제 selected에서
correct아니면 wrong으로 넘어가게 하고 싶습니다
해당 답변이 정답인지 오답인지 알게 되는 시점의 경우입니다
이를 위해선
answerState를 다시 사용합니다
왜냐하면 이 상태가 정답인지 오답인지
설정될 것이기 때문입니다
이를 위해서 아래의 JSX 코드에서
또 하나의 if 블록을 넣어줍니다
여기서 if answerState가 correct와 동일한지
wrong과 동일한지 체크하는 곳입니다
그리고
그것을 괄호로 감싸겠습니다
그리고 답변이 선택되었다면
그런 경우라면
대신 cssClass를 answerState로 설정합니다
즉 정답과 오답입니다
그리고 나서 버튼에 적용되는 것은 cssClass입니다
그렇게 하고
저장하고 돌아가보면
답변을 선택하면
강조 표시가 되는 것이 보입니다
그리고 정답인지 오답인지 표시됩니다
보이시는 것처럼
클릭할 때마다 여기저기 튀듯 표현됩니다
이 부분은 오류라고 할 수 있습니다
왜 이렇게 갑자기 바뀔까요?
왜 잘 작동하지 않는 것일까요?