발생한 문제 1
테스트 페이지에서 테스트 제출하기 버튼을 누른 뒤 테스트 결과 페이지에 불러올 TestResult 상태를 콘솔에 찍어보았는데 데이터에 유저정보값인 userId와 nickname만 조회되지않았다.
// 테스트 결과 페이지
const TestResultPage = () => {
const [testResult, setTestResult] = useState({});
useEffect(() => {
const getResult = async () => {
const result = await getTestResults();
setTestResult(result);
};
getResult();
}, []);
console.log("testResult :>> ", testResult);
🚨 문제 원인
그래서 테스트 페이지의 user를 콘솔에 찍어보니 유저정보를 담고있는 객체가 아니라 함수를 담고있었다.
// 테스트 페이지
// 수정 전
const user = async () => {
const token = localStorage.getItem("accessToken");
const response = await axios.get(
`${API_URL}/user`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
return response.data;
};
const handleTestSubmit = async (answers) => {
const result = calculateMBTI(answers);
const resultData = {
userId: user.id,
nickname: user.nickname,
result,
answers,
date: new Date().toISOString(),
visibility: true,
};
await createTestResult(resultData);
navigate("/testresult");
};
✅ 해결 방법
함수명이 헷갈릴 수 있으므로 user를 getUser로 바꾼 후 handleTestSubmit 함수에서 getUser를 실행한 값을 user에 담아주니 user 정보가 잘 불러와지는 것을 볼 수 있었다.
// 수정 후
const getUser = async () => {
const token = localStorage.getItem("accessToken");
const response = await axios.get(
`${API_URL}/user`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
return response.data;
};
const handleTestSubmit = async (answers) => {
const user = await getUser();
const result = calculateMBTI(answers);
const resultData = {
userId: user.id,
nickname: user.nickname,
result,
answers,
date: new Date().toISOString(),
visibility: true,
};
await createTestResult(resultData);
navigate("/testresult");
};
그리고 다시 테스트 결과 페이지에서 TestResult 콘솔을 찍어보니 값들이 전부 잘 들어오는 것도 확인할 수 있었다.
발생한 문제 2
테스트 페이지에서 결과 제출 버튼을 누르면 테스트 결과 페이지로 이동하고, 테스트 결과 페이지에는 방금 제출한 결과를 내보내야 한다. testResult 상태에는 이전에 제출한 객체들이 쌓이므로 방금 제출한 값을 보여주기 위해 userResult로 마지막 객체를 가지고 왔다.
const TestResultPage = () => {
const [testResult, setTestResult] = useState({});
useEffect(() => {
const getResult = async () => {
const result = await getTestResults();
setTestResult(result);
};
getResult();
}, []);
// testResult가 빈 값일 경우의 예외상황을 처리
if (testResult.length === 0) {
return <div>테스트 데이터가 없습니다.</div>;
}
// testResult의 마지막 객체 (방금 제출한 테스트 결과)를 userResult 에 담아줌
const userResult = testResult[testResult.length - 1];
return (
<div>
<h1>
{userResult.nickname}님의 테스트 결과 : {userResult.result}
</h1>
<p>설명</p>
<button>결과 페이지로 이동하기</button>
</div>
);
};
export default TestResultPage;
userResult 로 위와 같이 UI 를 구현한 뒤 새로고침을 했는데 값들이 빈값이 되면서 오류가 발생했다.
🚨 문제 원인
첫 렌더링 시 testResult 값이 빈 객체이고, useEffect 로 비동기 함수 실행이 완료된 뒤에 testResult에 값이 담기게 되므로 새로고침을 하게되면 nickname 값을 못 불러올뿐더러 아예 userResult 가 undefined 이므로 당연스럽게 오류가 발생한 것이었다.
✅ 해결 방법
옵셔널 체이닝 ".?" 을 사용해서 문제를 해결했다.
testResult 값이 없어도 오류를 내보내지 않고 첫 렌더링 시에는 undefined를 내보내고, useEffect 가 실행 완료 되면 testResult 에 값이 들어오게되면서 리렌더링이 되므로 화면에 정상적으로 값을 출력한다.
return (
<div>
<h1> // 옵셔널 체이닝 사용
{userResult?.nickname}님의 테스트 결과 : {userResult?.result}
</h1>
<button>결과 페이지로 이동하기</button>
</div>
);
🧐 느낀점
문제를 해결하고 나서 천천히 다시 코드를 보면 왜 오류가 났는지 이해가 잘 되는데 막상 오류에 부딪혔을 때는 뇌정지가 왔는지,, 계속 삽질하면서 동굴에 갇혔던 것 같다. 앞으로도 계속 오류들을 마주할텐데 이런 경험들이 쌓이고 쌓이다보면 조금이나마 덜 힘들게 해결할 수 있지 않을까.?
'TIL' 카테고리의 다른 글
Github PR 로만 merge 하도록 설정 (0) | 2024.09.12 |
---|---|
개인과제 - MBTI 성격 유형 테스트 ③ (2) | 2024.09.11 |
개인과제 - MBTI 성격 유형 테스트 ① (0) | 2024.09.09 |
Axios, TanStack Query, Zustand, 인증/인가 (1) | 2024.09.06 |
git pull 동기화 전략 (0) | 2024.09.05 |