좋아요 컴포넌트를 만들었는데 좋아요한 정보를 못 받아온다면 에러처리를 어떻게 할까 고민해보았다!
react에 default prop을 주는 방법이다.
const PostLikeShareButton = (prop: PostLikeSharebuttonProps) => {
return (
<PostLikeShareStickyBox top={10} left={1}>
<CircleButton onClick={prop.onLikeToggle} active={prop.liked}>
<LikeIcon fill={prop.liked ? 'red' : 'gray'} />
</CircleButton>
<div>{prop.likeCount}</div>
<CircleButton />
</PostLikeShareStickyBox>
);
};
PostLikeShareButton.defaultProps = {
likeCount: 0,
};
결과물을 보면 네트워크 연결 안 되어 있는 상황에서 0으로 떠있다.
0이 서버에 저장된 좋아요 수인지 네트워크로 받아오기 전인지 알 수 없다는 점에서 탈락!
jsx에서 값이 없다면 디폴트 값을 렌더링하는 방법이다.
const PostLikeShareButton = (prop: PostLikeSharebuttonProps) => {
return (
<PostLikeShareStickyBox top={10} left={1}>
<CircleButton onClick={prop.onLikeToggle} active={prop.liked}>
<LikeIcon fill={prop.liked ? 'red' : 'gray'} />
</CircleButton>
<div>{prop.likeCount === undefined ? '-' : prop.likeCount}</div>
<CircleButton />
</PostLikeShareStickyBox>
);
};
or을 이용해 값이 없으면 -를 출력한다.
'-'로 처리하니 문제가 생긴 티가 팍팍 난다!
그래도 역시 콘솔에서 보니 네트워크 에러라고 떠 있지만,
어떤 사용자는 정확히 무슨 네트워크 에러인지 궁금할 것이다. '무엇을 못 받아온거지? 왜 못 받아온거지?'
Q. error가 왜 2개나 있나요?
- 제 로직의 오류가 있습니다.. 뒤에서..
일반적으로 우린 console.error로 error를 출력한다. 그래서 network error가 났다는 소리를 볼 수 있었다.
useEffect(() => {
axios({
baseURL: API_HOST,
url: `/${userId}/liked/${post.id}`,
})
.then(reponse => {
setLiked(reponse.data.length !== 0);
})
.catch(error => {
console.error(error);
});
}, [post.id, userId]);
그러나 지식이 없는 사람은 무슨 action을 취해야 하는지 모를 수 있다.
그러면 디테일하게 에러 처리를 해줄 수 있는데, 만약 로그인을 반드시 해야한다면 로그인 페이지로 리다이렉트한다거나 할 수 있다. 근데 좋아요 정보를 못 가져왔다고 포스트 글을 못 보면 회원가입 필수라는 소리
.catch(error => {
console.error(error);
if (user.username === '') {
console.error('로그인 해주세요!');
navigate('/login');
}
});
또한, 게시글이 없는 페이지로 가면 not found page를 보여줄 수도 있다. 없는 주소는 url history에 남길 필요없으니 replace true 옵션으로 기존 history를 지워버려도 좋을 것으로 보인다.
useEffect(() => {
axios({
baseURL: API_HOST,
url: `/@${userId}/${urlSlug}`,
})
.then(response => {
setPost(response.data);
})
.catch(error => {
console.error(error);
if (error.response.status === 404) {
navigate('/NotFound', { replace: true });
}
});
}, [userId, urlSlug, navigate]);
지난 번에 useEffect를 병렬적으로 사용해 post 글 요청, 나의 좋아요한 정보 요청을 따로 한 상태였다
useEffect(() => {
axios({
baseURL: API_HOST,
url: `/@${userId}/${urlSlug}`,
})
~~~~
}, [~~~]);
useEffect(() => {
axios({
baseURL: API_HOST,
url: `/${user.username}/liked/${_post.id}`,
})
~~~~
}, [~~~]);
두 API 요청 쿼리에서 값의 의존성이 없을거라 생각하고 했는데 확인이 미흡했다.
그래서 서버에서 API를 하나로 합쳐 제공할 예정이다 (= API 설계 에러)
임시로 처리한 방법은 post 글 응답 받은 후인 then 안으로 좋아요 요청을 옮겨두었다.
useEffect(() => {
axios({
baseURL: API_HOST,
url: `/@${userId}/${urlSlug}`,
})
.then(response => {
const _post = response.data;
setPost(_post);
if (user.username !== '') {
// 서버 api 수정까지 연달아 요청(post.id 의존성)
// API 수정 예정: post + liked join (= SinglePost type)
axios({
baseURL: API_HOST,
url: `/${user.username}/liked/${_post.id}`,
})
.then(reponse => {
setLiked(reponse.data.length !== 0);
})
.catch(error => {
console.error(error);
});
}
})
.catch(error => {
console.error(error);
if (error.response.status === 404) {
navigate('/NotFound', { replace: true });
}
});
}, [navigate, urlSlug, user.username, userId]);