오늘은 React를 사용해 퀴즈 애플리케이션의 여러 기능을 구현하는 방법을 배웠습니다. 특히, 동적 상태 관리와 API 통신을 통해 사용자의 인터랙션을 처리하는 방법에 대해 배웠습니다.
1. 상태 관리와 동적 UI 구현
React의 useState와 useLocation 훅을 사용하여 여러 상태를 관리하고, 페이지의 동적 요소를 업데이트할 수 있었습니다. 예를 들어, 퀴즈 세션 정보(session_no, selectedCategory, quizCount 등)와 사용자 선택에 따라 변경되는 상태를 관리하고, 이를 기반으로 UI를 업데이트할 수 있었습니다.
const [session_no, setSessionNo] = useState(location.state?.session_no || null);
const [selectedCategory, setSelectedCategory] = useState(location.state?.selectedCategory || null);
const [quizCount, setQuizCount] = useState(location.state?.quizCount || 10);
상태를 useState로 정의하여 초기값을 설정하고, 이후 상태 변경이 필요할 때 setState 함수를 호출합니다. 예를 들어, setSelectedCategory를 사용하여 카테고리를 선택하고, 이를 바탕으로 퀴즈를 생성할 수 있습니다.
2. 드롭다운 토글 구현
두 개의 드롭다운을 토글하는 기능을 구현했습니다. 사용자가 하나의 드롭다운을 열면 다른 드롭다운은 자동으로 닫히도록 설정했습니다. 이를 위해 isDropdownOpen1과 isDropdownOpen2 상태를 각각 관리하며, 드롭다운이 열릴 때마다 상태를 업데이트합니다.
const toggle1Dropdown = () => {
setIsDropdownOpen1((prev) => !prev);
setIsDropdownOpen2(false);
};
const toggle2Dropdown = () => {
setIsDropdownOpen2((prev) => !prev);
setIsDropdownOpen1(false);
};
이 방식은 사용자가 다른 드롭다운을 열기 전, 먼저 열린 드롭다운을 닫을 수 있도록 도와줍니다.
3. 퀴즈 제출 및 피드백 처리
퀴즈를 제출하고 API로부터 피드백을 받는 기능을 구현했습니다. 사용자가 선택한 답안을 서버로 보내면, 서버는 해당 답안에 대한 피드백을 제공하고 이를 모달 창으로 띄웁니다. quizApiRequest를 사용해 API 요청을 보내고, 결과를 처리하는 과정이 핵심이었습니다.
const handleSubmit = async (e) => {
e.preventDefault();
try {
const dataToSubmit = Object.keys(selectedOptions).map((quizNumber) => ({
q_number: parseInt(quizNumber, 10),
c_number: selectedOptions[quizNumber],
}));
setIsLoading(true);
const response = await quizApiRequest.post(`/${session_no}/`, {
answers: dataToSubmit,
});
const feedback_response = await quizApiRequest.get(
`/feedback/${session_no}/`
);
setFeedbackContent(feedback_response.data.total_feedback);
setIsLoading(false);
setShowModal(true);
} catch (error) {
console.error("Error submitting quiz answers:", error);
setIsLoading(false);
}
};
피드백을 받으면 setFeedbackContent를 통해 내용을 업데이트하고, setShowModal(true)로 모달 창을 열어 사용자에게 피드백을 제공합니다.
4. 퀴즈 생성 및 세션 관리
새로운 퀴즈를 생성할 때, 사용자가 선택한 카테고리와 제목 등을 기반으로 퀴즈를 요청합니다. 퀴즈 생성 후에는 서버로부터 질문 목록을 받아와서 상태를 업데이트하며, 사용자가 선택할 수 있는 선택지를 보여줍니다.
const handleGenerateQuiz = async (e) => {
e.preventDefault();
setIsGenerateLoading(true);
const formData = {
category: selectedCategory,
title_no: selectedTitleIndex,
type: quizType,
count: quizCount,
difficulty: quizDifficulty,
keyword: selectedKeyword,
level: "beginner",
};
try {
const response = await quizApiRequest.post("/request/", formData);
const session_no = response.data.id;
setSessionNo(session_no);
const get_question_response = await quizApiRequest.get(`/${session_no}/`);
const questions = get_question_response.data.questions;
setSelectedQuestions(questions);
} catch (error) {
console.error("Error generating quiz:", error);
} finally {
setIsGenerateLoading(false);
}
};
퀴즈를 생성하기 위해 필요한 데이터를 서버로 보내고, 성공적으로 생성된 후 질문들을 받아와서 상태를 갱신합니다.
5. 선택한 옵션 저장 및 체크
사용자가 각 퀴즈에 대해 선택한 답안을 상태로 관리하며, selectedOptions 객체를 통해 관리됩니다. 선택된 답안은 handleSelectOption 함수에서 처리하며, 이 값을 바탕으로 퀴즈 제출 시 서버에 전송됩니다.
const handleSelectOption = (quizNumber, option) => {
setSelectedOptions((prevSelectedOptions) => ({
...prevSelectedOptions,
[quizNumber]: option,
}));
};
React를 활용해 동적인 상태 관리, API 통신, 모달 창 표시 등 다양한 기능을 구현할 수 있었습니다. 상태 관리와 이벤트 처리 로직을 잘 이해하고 활용하는 것이 중요하다는 것을 다시 한번 느꼈습니다. 특히, useState와 API 요청을 결합하여 실시간으로 사용자 인터페이스를 업데이트하는 방식에 대해 익숙해졌습니다. 이 경험을 통해 복잡한 상태 관리 및 동적 기능을 더 효율적으로 구현할 수 있을 것입니다.