ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Social Media 만들기 - 14) like, unlike post 구현하기
    NODE.JS 2021. 7. 13. 21:36

    이제 포스트 좋아요를 누르는 것을 구현하자. 

     

    postROuter.js

     

    postRouter.patch('/:id/like',auth, async(req,res)=>{
        try{
            const post = await Post.find({_id:req.params.id, likes:req.user.id})
            if(post.length>0) return res.status(400).json({msg:'You already liked this photo.'})
    
            const likedpost = await Post.findOneAndUpdate({_id:req.params.id},{
                $push:{likes:req.user.id}
            },{new:true})
    
            if(!likedpost) return res.status(400).json({msg:'This post does not exist.'})
    
            res.json({
                likedpost
            })
    
        }catch(err){
            return res.status(500).json({message:err.message})
        }
    } )

     

     

     

     

     

    Post Constants.js

    export const LIKE_POST_REQUEST = 'LIKE_POST_REQUEST'
    export const LIKE_POST_SUCCESS = 'LIKE_POST_SUCCESS'
    export const LIKE_POST_FAIL = 'LIKE_POST_FAIL'
    export const LIKE_POST_RESET = 'LIKE_POST_RESET'
    
    export const UNLIKE_POST_REQUEST = 'UNLIKE_POST_REQUEST'
    export const UNLIKE_POST_SUCCESS = 'UNLIKE_POST_SUCCESS'
    export const UNLIKE_POST_FAIL = 'UNLIKE_POST_FAIL'
    export const UNLIKE_POST_RESET = 'UNLIKE_POST_RESET'

     

    PostActions.js

    export const likePost = (post) => async (dispatch, getState)=>{
        dispatch({
            type:LIKE_POST_REQUEST,
            payload:{loading:true}
        })
    
        const {userLogin:{userInfo}} = getState()
        try{
            const res = await axios.patch(`/api/post/${post._id}/like`,null, {
                headers:{authorization:`Bearer ${userInfo.token}`}
            })
            dispatch({
                type:LIKE_POST_SUCCESS,
                payload:res.data.likedpost
            })
    
        }catch(error){
            dispatch({
                type:LIKE_POST_FAIL,
                payload:                
                error.response && error.response.data.message
                ? error.response.data.message
                : error.message
            })
        }
    }
    
    export const unlikePost = (post) => async (dispatch, getState)=>{
        dispatch({
            type:UNLIKE_POST_REQUEST,
            payload:{loading:true}
        })
    
        const {userLogin:{userInfo}} = getState()
        try{
            const res = await axios.patch(`/api/post/${post._id}/unlike`,null, {
                headers:{authorization:`Bearer ${userInfo.token}`}
            })
            dispatch({
                type:UNLIKE_POST_SUCCESS,
                payload:res.data.unlikedpost
            })
    
        }catch(error){
            dispatch({
                type:UNLIKE_POST_FAIL,
                payload:                
                error.response && error.response.data.message
                ? error.response.data.message
                : error.message
            })
        }
    }

     

    postReducers.js

    export const postLikeReducer = (state={}, action)=>{
        switch(action.type){
            case LIKE_POST_REQUEST:
                return {loading:true, success:false}
            case LIKE_POST_SUCCESS:
                return {loading:false, success:true, likedpost:action.payload}
            case LIKE_POST_FAIL:
                return {loading:false, success:false, error:action.payload}
            case LIKE_POST_RESET:
                return {}
            default:
                return state
        }
    }
    
    export const postUnlikeReducer = (state={}, action)=>{
        switch(action.type){
            case UNLIKE_POST_REQUEST:
                return {loading:true, success:false}
            case UNLIKE_POST_SUCCESS:
                return {loading:false, success:true, unlikedpost:action.payload}
            case UNLIKE_POST_FAIL:
                return {loading:false, success:false, error:action.payload}
            case UNLIKE_POST_RESET:
                return {}
            default:
                return state
        }
    }

     

    store.js

        likepost:postLikeReducer,
        unlikepost:postUnlikeReducer,

     

     

    CardFooter.js

    (likebutton을 따로 빼주어서 표현해줄 것이다. )

    function CardFooter({post}) {
        const [isLike, setIsLike] = useState(false)
    
        const dispatch = useDispatch()
    
        const userLogin = useSelector(state => state.userLogin)
        const {userInfo} = userLogin
    
        useEffect(() => {
            if(post.likes.find(like=> like._id===userInfo.user._id)){
                setIsLike(true)
            }else{
                setIsLike(false)
            }
        }, [post.likes, userInfo.user._id])
    
        const handleLike = () =>{
            if(!isLike){
                dispatch(likePost(post))
            }else{
                dispatch(unlikePost(post))
            }
            setIsLike(!isLike)
    
        }
        
        
                            <LikeButton isLike = {isLike} handleLike={handleLike} />

     

     

    LikeButton.js

    import React from 'react'
    import { useSelector } from 'react-redux'
    
    function LIkeButton({isLike, handleLike}) {
    
        const theme = useSelector(state => state.theme)
        
        return (
            <>
    {            console.log(isLike)
    }            {
                    isLike
                    ? <i className="fas fa-heart" onClick={handleLike} style={{filter: theme? 'invert(1)': 'invert(0)'}}></i>
                    : <i className="far fa-heart" onClick={handleLike}></i>
    
                }
            </>
        )
    }
    
    export default LIkeButton

     

    좋아요를 누르면 다음과 같이 표시되고, 

     

    db에도잘 추가된다. 

     

     

    다시 좋아요를 해제하면, 

     

     

    db에서도 삭제된다. 

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

Designed by Tistory.