토이프로젝트: 공감 기능 에러 핸들링

coolchaem·2022년 4월 19일
1

toyproject

목록 보기
14/21

좋아요 컴포넌트를 만들었는데 좋아요한 정보를 못 받아온다면 에러처리를 어떻게 할까 고민해보았다!

default prop

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에서 조건부 렌더링

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개나 있나요?

  • 제 로직의 오류가 있습니다.. 뒤에서..

axios error handle

일반적으로 우린 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 병렬 요청

지난 번에 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]);
profile
Front-end developer

0개의 댓글