이 섹션을 끝내고
이 퀴즈를 끝내기 위해
'퀴즈 완료' 스크린을 만들겠습니다
이를 진행하면서 얼마나 많은 질문이 정답이었고
얼마나 많은 질문이 오답였는지를
사용자에게 보여주겠습니다
또 건너뛴 질문의 숫자도 알려주겠습니다
그리고 모든 질문에 대한 세부사항을 보여주겠습니다
이를 위해 새로운 컴포넌트를 추가합니다
이름은 Summary고
Summary.jsx (요약 파일)에 추가하겠습니다
그리고 컴포넌트 함수 또한 Summary로 이름 짓습니다
그리고 나서, Summary의 ID로
디브를 하나 반환하겠습니다
그리고 마지막으로 (Quiz.jsx (퀴즈 파일)에 이미 있는
여기 이 디브를
잘라내서
Quiz 파일로부터 Summary 파일로 옮겨줍니다
그리고 또한 그 image import도 가져와야 합니다
그래서 Quiz 파일로부터 지운 후에
요약 파일로 옮겨오겠습니다
여기에서 이미지를 가져오겠습니다
그리고 나서 여기 H2 요소 아래에
summary-stats라는 ID의 디브를 만들어 줍니다
여기에서 개요를 보여주겠습니다
그리고 여기서의 목표는 다수의 문단를 가지는 것이고
모든 문단은 span을 가집니다
이 span은 퍼센트 숫자를 가지는데, 예를 들어 건너 뛴 질문의 10퍼센트로 하겠습니다
className에 number를 넣어 형식을 편집하고
그리고 두 번째 span에는 className text를 추가해서
skipped라고 작성합니다
그리고 해당 문단을 복사하고 두 번 반복합니다
그래서 올바르게 답변된 질문과 틀리게 답변된 질문들을
출력할 수 있게 됩니다
그리고 저 퍼센트 숫자는
사용자가 선택한 답변을
기반으로 하여 동적으로 파생되어야 합니다
summary-stats라는 디브 옆에
순서 있는 목록을 추가하겠습니다
모든 질문에 대한 상세 정보를 출력하는 곳입니다
그래서 끝에 목록 항목을 내보내되
각 목록 항목은 H3 요소를 가집니다
질문의 숫자를 출력하겠습니다
예를 들어 2를 쓰고 문단을 추가해서
여기에서 문제 텍스트를 추가하겠습니다
그리고 여기에 className을 넣어 줍니다
형식 수정을 위해서입니다
여기에 문제에 대한 텍스트를 넣고
그리고 className을 넣어서 또 다른 문단을 생성해줍니다
이 className에 사용자 답변을 출력할 user-answer을 넣어줍니다
이 부분은 모두 실제 데이터로
교체될 예정입니다
그러므로 그 데이터를 모아야 합니다
이미 그 작업을 해 둔 것이 있는데
바로 Quiz.jsx(퀴즈 파일)에서
선택된 모든 답변들을 보관하는 중입니다
이 부분이 각 정보의 핵심입니다
왜냐면 그들은 선택된 답변들의
목록으로서 여기의 모든 숫자를 계산하는데
사용될 수 있기 때문입니다
그리고 여기 세부사항을 출력하겠습니다
그리고 Quiz 컴포넌트 파일 마지막에
방금 다뤘던 Summary 컴포넌트 파일을
사용하겠습니다
그리고 여기에 Summary를 Summary.jsx(요약 파일)에서
가져오겠습니다
그리고 이 Summary 컴포넌트를 여기에 출력하겠습니다
이제 퀴즈가 끝나면
사용자의 답변을 속성으로서
Summary 컴포넌트에 전달할 수 있습니다
그래서 여기 값으로서 제공하고 싶은
userAnswers 상태값을
userAnswers 속성을 Summary에 넣어줍니다
물론 속성 이름은 달라도 됩니다
하지만 저는 userAnswers로 계속 사용 하겠습니다
그리고 Summary 컴포넌트에서
속성 객체를 구조 분해(destructure)하여
userAnswers 객체를 구하겠습니다
그리고 이 userAnswers 객체를 이용해서
해당 컴포넌트에 필요한 모든 각각의 데이터를
파생해 줍니다
예를 들어, 답변들과 질문들을 여기 아래에
출력해줍니다
그걸 위해 질문들 또한 필요합니다
QUESTIONS를 가져오되
한 층위 올라가서 questions.js에서 불러옵니다
그렇게 하면 미처리 질문 데이터도 이용 가능해집니다
여기 순서 있는 항목에 가져왔으니
사용자의 답변에 기반해서 userAnswers를 매핑하여
항목 목록을 내보낼 수 있습니다
그리고 여기에 목록 항목을 반환하겠습니다
각 답변에
answer을 출력하고 여기에 키를 추가해줍니다
이 또한 answer가 될 수 있죠
이 것이 모든 answers를 통틀어서 독특한 값이 되기에
여기 answer이 속한 질문의 번호를
인덱스의 도움으로 출력할 수 있습니다
이 또한 맵으로 전달한 이 함수에서
자동으로 얻는 값입니다
자바스크립트에서 제공하는 기능입니다
그리고 그 인덱스는 0부터 시작합니다
그래서 인덱스 + 1을 출력해 줍니다
첫 번째 질문에 숫자 1을 표시하도록 하기 위해서입니다
숫자 2는 두 번째 질문, 이런 식으로 진행됩니다
그리고 question 텍스트를 출력하기 위해서
질문의 미처리 데이터를 사용할 수 있습니다
그리고 인덱스를 이용해서 각각의 답변이 속한
질문들에 접근합니다
그리고 나서 해당 question의 텍스트를 여기에 내보냅니다
이제 저장하고 보면 여기 화면에 질문의 목록이
생긴 것을 볼 수 있습니다
그리고 또한 어떤 답변을 골랐는지 볼 수 있습니다
모든 질문에 대해서 볼 수 있습니다
이제 유저가 타이머가 만료되기 전
질문을 건너뛰는 것도
가능합니다
그렇게 되면 아래에 항상 답변을 출력하는 대신
답변이 선택되지 않았다면 널값을 나타내도록 하는 겁니다
왜냐하면 이 경우, Quiz 컴포넌트에서
타이머가 만료되면 답변으로 널값을 보관하고 있습니다
즉 답변이 선택되지 않았다는 의미입니다
널값을 이 아래에 출력하는 대신
답변이 True한지 확인해야 합니다
그리고 fallback(대체)값으로
답변이 선택되지 않았다면 '건너뜀'을 출력하겠습니다
또 조건적으로 여기에 className을 설정해서
이를 화면에 띄워서 사용자에게
정답인지 아닌지 보여주겠습니다
그걸 하기 위해선 cssClass를 동적으로 파생합니다
지금 보고 있는 Answers를 위해
여기에 추가되어야 합니다
그리고 cssClass 변수를 추가하겠습니다
이는 항상 user-answer입니다
그래서 이게 항상 추가되어야 하는 기초 cssClass입니다
그런데 여기에서 if (answer)이 널과 일치하는지 확인할 수 있습니다
이는 답변을 건너뛰었다는 뜻이고
이 경우, 이 문자열에
공백을 추가하고
그 후 skipped라는 cssClass를 추가합니다
답변이 건너뛰어졌을 때 특별한 형식을 적용하기 위함입니다
다른 경우라면 답변을 선택했을 것이므로 확인을 해야 합니다
그러면 현재의 인덱스에서 answer이 questions에
일치하는지 확인하는데
그 곳에서 첫 번째 답변이
정답이라는 것을 아므로
True값으로 나올 때
답변이 선택되었다는 것을 알 수 있습니다
이 경우 correct cssClass를 여기에 추가하겠습니다
그리고 여기 이 공백은 매우 중요합니다
이 문자열로 연결할 때
cssClasses들을 공백을 이용해서
격리하는 겁니다
그리고 마지막으로 마지막 else에
답변이 선택되었다는 것을 우리는 압니다
이는 틀린 답변이므로
여기에 wrong cssClass를 추가합니다
그리고 여기에 else if문을 넣어줘야합니다
if 키워드를 넣는 걸 깜빡했습니다
그리고 이 cssClass가 여기 아래에 추가되어야 합니다
작업이 끝났으니 확인해 보겠습니다
틀린 답변은 빨간색 텍스트입니다
그리고 올바른 답, 정답은 초록색 텍스트입니다
이제 우리는 또한 요약 통계가 필요합니다
이를 위해서 모든 답변을 확인해서
건너 뛴 답변, 틀린 답변, 맞은 답변의
몫을 계산할 필요가 있습니다
그래서 일단 userAnswers를 보고 건너 뛴 몫을
계산하는 것으로 시작해봅시다
널과 일치하는 answer들을
필터링합니다
왜냐하면 말씀드렸듯 만약 답변이 건너 뛰어졌다면
여기 answers 배열에 널을 추가해서
건너뛴 답변을 얻게 되기 때문입니다
정답은 미처리 데이터의 첫 번째 답변과
일치하는 모든 답변이라고
볼 수 있습니다
그러므로 여기 answers 배열에
해당 answer에 인덱스가 필요합니다
그래서 questions 미처리 데이터 배열에서
정답을 선택할 수 있도록 합니다
그리고 우린 해당 답변을
미처리 데이터의 첫 번째 답변들과 대조해 보겠습니다
동일하면 우리는 해당 답변이 정답이라는 것을 알 수 있습니다
그리고 이는 correctAnswers에 추가될 겁니다
그러고 나서는
건너뛴 답변의 몫을 계산할 수 있습니다
그러니 여기에 skippedAnswersShare를 넣어줍니다
그리고 skippedAnswers array의 길이를 가져옵니다
그래서 우리가 가진 건너뛴 답변들의 수를
종합적인 답변의 길이로 나눕니다
그래서 우리가 가진 답변의 총 수를
100으로 곱해줍니다
그리고 Math.round를 사용해서 종합 결과를 반올림 해줍니다
그리고 같은 로직을
정답에 적용시킬 수 있고
올바른 답변 몫은
간단하게 correctAnswers 길이를
userAnswers 길이로 나눈 값입니다
그리고 틀린 답변 몫은
그리고 당연하게도 100 빼기 건너뛴 답변 몫
빼기 올바른 답변 몫이 되겠죠
그래서 남는 값이 틀린 답변 몫이 됩니다
그렇게 다 계산하고 여기에 skippedAnswersShare를 내보냅니다
그리고 그 후에 퍼센트 기호를 유지해 줍니다
즉 그 기호를 화면에서 볼 수 있게 됩니다
그리고 여기엔 correctAnswersShare를 넣어줍니다
그리고 마지막 요약 통계 숫자로는
WrongAnswersShare를 넣어줍니다
이걸 저장하고 숫자들을 한 번 보면
설정한 대로 잘 작동하는지 확인하기 위해서
퀴즈를 진행해 봅시다
첫 번째 질문은 시간이 만료되게 놔둘 겁니다
답변을 선택하지 않고
그러고 나서 다음 질문은 답변을 합니다
답은 틀린 것 같습니다
그 다음 건 올바른 답을 선택해보겠습니다
그리고 다시 다음 질문은
넘어가게 두겠습니다
앱이 올바르게 작동하고
그리고 요약 화면에 잘 반영되는지 확인하기 위함입니다
여기 다시 답을 골라봅시다
저는 틀렸지만 여러분은 더 잘 하실 수 있을겁니다
여기서도 답변을 고르고
마지막 질문은
틀린 답안을 선택해줍니다
그렇게 하고 나니 마지막 화면이 나오고
모두 잘 작동하는 것처럼 보이네요
여러 개의 다른 질문을 받았고
두 개의 질문을 건너 뛰었고
두 개를 맞췄습니다
그러므로 그 두 가지가
같은 퍼센트 값을 가지게 됩니다
그리고 또한 틀린 답변의 퍼센트 값도 나왔습니다
3개를 틀렸습니다
잘 작동하는 것 같습니다
그런데 개발자 도구에서는
에러 하나가 뜹니다
두 개의 자식이 같은 키를 가진 것입니다
여기의 문제점은
건너뛴 두 개의 답변이 있고
그리고 답변들을 키로 사용하기에
널값 키를 두 번 사용한 것입니다
그것이 이유입니다
즉 인덱스가 더 나은 키입니다
보통은 해당 map 메소드의
인덱스 사용을 피해야 합니다
왜냐하면 이는 데이터와 묶여 있지 않기 때문입니다
그렇지만 대신에 배열 내 데이터 위치에 의해
만일 이 배열 내 두 항목이 자리를 바꾼다면
데이터는 바뀌지만 인덱스는 바뀌지 않습니다
위치 1이 아직 인덱스 0을 가지고 있기 때문입니다
여기서 볼 수 있습니다
답변을 교체하는 것이 아니기 때문에 괜찮습니다
이 목록에서 데이터를 바꾸는 것이 아닙니다
그리고 인덱스는 여기서 최고의 해결 방법이므로
이 부분을 바꾸겠습니다
여기 에러가 아직 있지만
다시 에러가 뜨지는 않을 겁니다
퀴즈를 다시 진행한다면 말입니다
그렇게 해서 퀴즈 작업이 전부 끝났습니다