새로고침 하지않고 실시간으로 응답값 출력하기

Kingmo·2022년 3월 20일
1

게시글 상세페이지에서 페이스북 처럼 좋아요, 싫어요를 누를 때마다 실시간으로 백엔드에서 몇 개나 눌렸는지 가져와서 보여주고 싶었다.

3시간을 삽질한 끝에 구현해냈다...😂

const LIKE_BOARD = gql`
    mutation likeBoard($boardId: ID!) {
        likeBoard(boardId: $boardId)
    }
`;
const DISLIKE_BOARD = gql`
    mutation dislikeBoard($boardId: ID!) {
        dislikeBoard(boardId: $boardId)
    }
`;

const BoardRoutedPage = () => {
  	// (**likeCount관련 코드를 dislikeCount도 동일하게 적용**)
  	// likCount에 빈값을 넣어 아래 return의 삼항연산자에 의해
  	// 처음 페이지 로드 시에 게시글을 불러올 떄 받은 likeCount 값이 나오게한다.
	const [likeCount, setLikeCount] = useState();
    const [dislikeCount, setDislikeCount] = useState();
  	const router = useRouter();
  
  // 클릭 이벤트로 mutation 코드를 실행하도록 설정.
  	const [likeBoard] = useMutation(LIKE_BOARD);
    const [dislikeBoard] = useMutation(DISLIKE_BOARD);
  
  // "좋아요" 클릭 시 동적 라우팅으로 반환 받은 [boardId]를 이용하여 백엔드에 좋아요 횟수를 올려달라 요청하는 함수 작성
 	const onClickLike = async () => {
        const resultLikeCount = await likeBoard({
            variables: {
                boardId: router.query.boardId,
            },
        });
      // 백엔드로 받은 응답을 useState를 이용해 "변수 likeCount"에 넣어준다
        setLikeCount(resultLikeCount.data.likeBoard);
    };
    const onClickDislike = async () => {
        const resultDislikeCount = await dislikeBoard({
            variables: {
                boardId: router.query.boardId,
            },
        });
        setDislikeCount(resultDislikeCount.data.dislikeBoard);
    };
  
  return (
    // 생략
    <FlexColumn className="yellowIcon cursorPointer">
      <ThumbUpAltOutlinedIcon onClick={onClickLike} />
      {likeCount
        ? likeCount
      : data
        ? data.fetchBoard.dislikeCount
      : "loading..."}
    </FlexColumn>
    <FlexColumn>
      <ThumbDownOutlinedIcon
        className="cursorPointer"
        onClick={onClickDislike}
        />
      {dislikeCount
        ? dislikeCount
      : data
        ? data.fetchBoard.dislikeCount
      : "loading..."}
    </FlexColumn>
  )
}
export default BoardRoutedPage;
{likeCount
	? likeCount
	: data
    ? data.fetchBoard.dislikeCount
	: "loading..."}

위의 삼항연산자는 아래 if문과 같은 의미이다.

if(likeCount) {
  likeCount
} else if(data) {
  data.fetchBoard.dislikeCount
} else {
  "loading..."
}

수시로 console.log를 사용해 데이터를 살펴보자.

게시글 페이지에서 좋아요 수가 data.fetchBoard.dislikeCount에 출력되었다고
그대로 복붙해서 좋아요 클릭 후 반환 받는 곳에서 사용해놓고 전혀 이상함을 못느꼈던 탓에 끊임없이 삽질을 했다.

likeCount를 useState로 선언하면 값이 바뀔때마다 리렌더링하고, 바뀌지않으면 똑똑하게 렌더링하지 않는다.

useEffect, useRef, useMemo까지 생판 모르는 것들을 구글링하며 시도했지만 결국 가장 익숙한 useState로 구현해냈다.
그러니 꼼수 부리지말고 배운거나 잘 써먹자.

profile
Developer

0개의 댓글