티스토리 뷰

안녕하세요 강정호입니다

 

오늘은 useMutation을 사용하여 좋아요 기능을 구현해보겠습니다.

 

PostQueries.js

좋아요와 댓글 추가 Graphql 쿼리를 호출하는 함수를 만듭니다.

import { gql } from "apollo-boost";

export const TOGGLE_LIKE = gql`
    mutation toggleLike($postId: String!){
        toggleLike(postId: $postId)
    }

`;


export const ADD_COMMENT = gql`
    mutation addComment($postId:String!, $text: String!){
        addComment(postId: $postId, text: $text){
            id
            text
            user {
                userName
            }
        }
    }
`;

 

PostContainer.js

useState의 사용 : 함수형 컴포넌트에서 좋아요 true / false 상태값을 변경시킨다. 이것은 서버에 값을 변경시키는 것이 아니라 사용자들이 View에서 좋아요 상태값을 바로 확인할 수 있도록 한다.

useMutation의 사용 : 실제로 서버에 좋아요를 반영시키는 역할을 한다.

 

//useMutation을 사용하면 반환할때 함수, 데이터를 배열로 반환 --> 이부분 확인하기
    const [toggleLikeMutation] = useMutation(TOGGLE_LIKE, {
        variables: { postId: id }
    });
    
    
    const toggleLike = async () => {
        
        if(isLikedState === true){
        	// View에서 보여지는 상태값만 변경하는 부분
            setIsLiked(false);
            
            // 좋아요 숫자를 표현
            setLikeCount(likeCountState - 1);
        }else{
            setIsLiked(true);
            setLikeCount(likeCountState + 1);
        }
		
        // 실제로 좋아요 상태값을 서버에 반영하는 부분
        toggleLikeMutation();
    };

    return (
        <PostPresenter
            user={user}
            files={files}
            likeCount={likeCountState}
            isLiked={isLikedState}
            comments={comments}
            createdAt={createdAt}
            newComment={comment}
            setIsLiked={setIsLiked}
            setLikeCount={setLikeCount}
            currentItem={currentItem}
            
            // PostPresenter View에 toggleLike 함수를 넘겨서 onClick 할때마다 상태값을 변경할 수 있도록 한다
            toggleLike={toggleLike}
        />

    );
}

 

PostPresenter.js

좋아요 버튼을 onClick 할때마다 toggleLike 함수를 호출하여 isLiked 상태값을 변화시켜서 빈 하트, 빨간색 하트가 보여질 수 있도록 한다

<Post>
        <Header>
            <Avatar size="sm" url={avatar} />
            <UserColumn>
                <FatText text={userName} />
                <Location>{location}</Location>
            </UserColumn>
        </Header>
        <Files>
            {files && files.map((file, index) => <File id={file.id} src={file.url} showing={index === currentItem}/>)}
        </Files>
        <Meta>
            <Buttons>
                <Button onClick={toggleLike}>{isLiked ? <HeartFull /> : <HeartEmpty /> }</Button>
                <Button>
                    <Comment />
                </Button>
            </Buttons>
            <FatText text={likeCount === 1 ? "1 like" : `${likeCount} likes`} />
            <Timestamp>{createdAt}</Timestamp>
            <Textarea placeholder="Add a comment..." {...newComment} />
        </Meta>
    </Post>

 

[테스트 결과]

 

댓글