ReadRiddle 개발기 - 2

Cookie Baking·2025년 1월 6일

AI 부트 캠프 TIL

목록 보기
37/42

Trouble Shooting 1

문제 : 같은 퀴즈 세션에 대해서만 답변, 결과가 업데이트 되던 문제

문제 원인:

현재 백엔드에서 가져오는 id 값은 퀴즈 세션의 id값이 아닌 존재하지 않은 값이기 때문에 나오는 디폴트 값인 1이었습니다.

백엔드 구조

post(self, request):
        
        # Debug
        print(request.data)

        content = llm.content
        chain = llm.quizz_chain(content)
        response = chain.invoke(request.data)
        response_dict = json.loads(response)
        quiz = Quiz.objects.create(
            title=response_dict["title"],
            description=response_dict["description"],
        )
        for question_data in response_dict["questions"]:
            question = Question.objects.create(
                quiz=quiz,
                number=question_data["id"],
                content=question_data["content"],
                answer_type=question_data["answer_type"],
            )
            for choice_data in question_data["choices"]:
                Choice.objects.create(
                    question=question,
                    number=choice_data["id"],
                    content=choice_data["content"],
                    is_correct=choice_data["is_correct"],
                )

        print(quiz.id, response_dict["questions"])
        return Response(
            {"detail": "문제가 생성되었습니다.", "id": response_dict["id"], "questions": response_dict["questions"]},
            status=status.HTTP_200_OK,
        )

즉, 백엔드 측에서 보내주는 id 값이 전체 퀴즈 세션의 id로 오해했기 때문에 발생했던 문제였습니다.

id를 실제 생성된 quiz의 id로 재설정해줘야 했습니다.
그 후 해당 id로 GET요청을 보내 안전하게 해당하는 퀴즈 세션의 정보를 가져올 수 있도록 수정했습니다. (id로 조회한 온전한 퀴즈 세션에 대한 정보 받아오기)

백엔드 측 변경사항

변경 전

 return Response(
            {"detail": "문제가 생성되었습니다.", "id": response_dict["id"], "questions": response_dict["questions"]},
            status=status.HTTP_200_OK,
        )

변경 후

 return Response(
            {"detail": "문제가 생성되었습니다.", "id": quiz.id, "questions": response_dict["questions"]},
            status=status.HTTP_200_OK,
        )

프론트 측 변경사항

백엔드에서 값을 id가 아닌 number로 그 고유성을 유지하고 있다.
이를 무시하고 quiz.id나 choice.id 를 통해 POST, GET 요청을 날렸기 때문에 일부 요청의 경우 (특히나 보기 문항이 많은 4지선다 문제) 에서 다르게 채점되는 상황이 발생했었다.

때문에 프론트 측에서도 id가 아닌 number로 그 통일성을 유지해준다.

<FormQuizContainer>
        {Array.isArray(selectedQuestions) &&
          selectedQuestions.map((quiz) => (
            <FormQuizCardContainer key={quiz.number}>
              <TitleContainer>
                Q{quiz.number}. {quiz.content}
              </TitleContainer>

              <QuizContentContainer>
                {quiz.answer_type === "ox" ? (
                  <Option2Container>
                    {quiz.choices.map((choice) => (
                      <Option2Button
                        key={choice.number}
                        className={selectedOptions[quiz.number] === choice.number ? "selected" : ""}
                        onClick={() => handleSelectOption(quiz.number, choice.number)}
                      >
                        {choice.content}
                      </Option2Button>
                    ))}
                  </Option2Container>
                ) : (
                  <OptionContainer>
                    {quiz.choices.map((choice) => (
                      <OptionButton
                        key={choice.number}
                        className={selectedOptions[quiz.number] === choice.number ? "selected" : ""}
                        onClick={() => handleSelectOption(quiz.number, choice.number)}
                      >
                        {choice.content}
                      </OptionButton>
                    ))}
                  </OptionContainer>
                )}
              </QuizContentContainer>
            </FormQuizCardContainer>
          ))}

Trouble Shooting 2

문제 : 네비게이션 바에서 프론트 측에서 화면 변환 시 상태 상속 안되던 문제

<Button  onClick={() => navigate("/chats/form")}>

const [selectedCategory, setSelectedCategory] = useState(null);
const [selectedTitle, setSelectedTitle] = useState(null);
const [selectedTitleIndex, setSelectedTitleIndex] = useState(null);

해결 : state로 상속되어야 하는 값들을 넘겨줌, 받은 화면 측에서는 useLocation을 이용해 navigation에서 넘어온 state를 가져올 수 있게 됨

        <Button
              onClick={() =>
                navigate("/chats/form", {
                  state: {
                    selectedCategory: selectedCategory,
                    selectedTitle: selectedTitle,
                    selectedTitleIndex: selectedTitleIndex,
                  },
                })
              }
            >
            
const [selectedCategory, setSelectedCategory] = useState(
        location.state?.selectedCategory || null
      );
      const [selectedTitle, setSelectedTitle] = useState(
        location.state?.selectedTitle || null
      );
      const [selectedTitleIndex, setSelectedTitleIndex] = useState(location.state?.selectedTitleIndex || null);

더 생각해볼 사항 : dom을 통해 가져온 값은 수명이 어느까지인가?

A.

DOM을 통해 가져온 값은 캐시값인가?에 대한 질문에 대해 해석하자면, 브라우저에서 useLocation을 사용하여 받은 값들이 실제로는 캐시된 값이냐는 것에 대한 궁금증인 것 같습니다.

답변:
useLocation으로 가져오는 값은 캐시된 값이 아니라 **상태(state)**입니다.
React Router의 navigate 메서드를 사용해서 state를 넘겨주면, 그 상태는 해당 페이지에서만 유효합니다. 즉, 페이지가 리로딩되거나 새로 고침될 때는 상태가 초기화되며, location.state는 더 이상 접근할 수 없습니다.
따라서 useLocation으로 받은 값은 브라우저 캐시와 관련이 없고, 오직 React Router의 상태 관리에 의해 관리됩니다.

상태(state) vs 캐시:
상태 (State): navigate를 통해 페이지 이동 시 state를 전달하면, 해당 페이지에서만 상태를 사용할 수 있고, 새로 고침이나 다른 라우팅으로 페이지를 나가면 사라집니다.
캐시 (Cache): 브라우저 캐시는 페이지를 새로 고침할 때 리소스를 빠르게 불러오기 위한 저장소입니다. 예를 들어, 이미지나 데이터 파일이 캐시되며, 이러한 데이터는 브라우저에 의해 자동으로 관리되고 저장됩니다.
따라서 useLocation은 캐시가 아니라, 페이지 간 이동 시 전달된 동적 데이터라고 이해하시면 됩니다.

새롭게 적용해본 사항

  • Loading 화면
  • navigation에서 화면 전환시 값 전달 적용
  • 퀴즈 세션에 따른 하위 퀴즈들 생성 및 저장 (API 연결)

0개의 댓글