본문 바로가기
REACT

[클론코딩] 무비앱 시리즈 #14

by kmyobin 2022. 7. 26.

#14 Favorite 페이지 (2)

 

저번에는 Favorite 페이지로 들어가면 내가 좋아요 한 영화의 제목, 시간이 뜨는 것까지 구현했다

오늘은 Remove를 누르면 삭제가 되는 것과 마우스를 갖다 대면 영화 스틸컷?이 나오는 것을 구현할 것이다

 

 

1. Popover되게 만들기

ant design에서 Popover을 가져온다(마우스를 갖다대면 작은 창이 뜸)

import {Popover} from 'antd';

 

Favorite 페이지에서 좋아요 한 영화들의 정보가 나오는 곳을 따로 빼서 만들어준다

  const renderCards = Favorites.map((favorite, index) => {
    return <tr key={index}>
        <Popover  title={`${favorite.movieTitle}`}>
          <td>{favorite.movieTitle}</td>
        </Popover>

        <td>{favorite.movieRunTime} mins</td>
        <td><button>Remove</button></td>
      </tr>
  })

 

이렇게 따로 빼서 작성한 후 <tbody>에 renderCards를 넣어준다

<tbody>
 {renderCards}
</tbody>

 

Favorite 페이지에서 직접 확인해보면

잘 구현되는 것은 일단 확인했다

 

 

2. Popover에 영화 사진 넣기

그럼 moviePost를 넣어보자

전에 Favorite.js 파일에서 

  const moviePost = props.movieInfo.backdrop_path

해줬던 moviePost를 써먹을 것이당

 

renderCards에 코드를 추가한다

    const content = (
      <div>
        {favorite.moviePost ? <img src={`${IMAGE_BASE_URL}w500${favorite.moviePost}`} /> : "no image"}
      </div>
    )

image 가져올 때 작은 따옴표(') 말고 `를 쓰도록 하자^^

moviePost가 있으면 출력하고, 없으면 no image라고 뜨게 만드는 것이다

엇~ 근데 IMAGE_BASE_URL은 Config에 있던 것이다~

import {IMAGE_BASE_URL} from '../../Config'

가져와주깅

 

이렇게 만들고 Popover 쓸 때 content={content}를 써준다

 

완성된 renderCards 코드는 아래와 같다

  const renderCards = Favorites.map((favorite, index) => {

    const content = (
      <div>
        {favorite.moviePost ? <img src={`${IMAGE_BASE_URL}w500${favorite.moviePost}`} /> : "no image"}
      </div>
    )
    
    return <tr key={index}>
        <Popover content = {content} title={`${favorite.movieTitle}`}>
          <td>{favorite.movieTitle}</td>
        </Popover>

        <td>{favorite.movieRunTime} mins</td>
        <td><button>Remove</button></td>
      </tr>
  })

 

그리고 웹 페이지를 확인하면

짜잔형

moviePost가 성공적으로 떴다

 

 

3. Remove 버튼 누르면 삭제되기

버튼을 클릭하면 삭제되는 event가 발생하는 것이므로 

<td><Button onClick = {() => onClickDelete(favorite.movieId, favorite.userFrom)}>Remove</Button></td>

클릭하면(onClick) onClickDelete라는 함수가 실행되게 만들었다

 

삭제를 할 때 movieId와 user 정보가 필요하기 때문에 parameter로 써주었다

  const onClickDelete = (movieId, userFrom) => {
    const variables = {
      movieId,
      userFrom
    }

    Axios.post('/api/favorite/removeFromFavorite', variables)
    .then(response => {
      if(response.data.success){
        fetchFavoritedMovie()
      }
      else{
        alert('리스트에서 지우는데 실패했습니다.')
      }
    })
  }

저 fetchFavoritedMovie 함수는 fetch 구문을 Remove를 누를 때 실행되어야 하므로 따로 만들어주었다

 

  const fetchFavoritedMovie = () => {
    Axios.post('/api/favorite/getFavoriteMovie', {userFrom: localStorage.getItem('userId')})
    .then(response => {
      if(response.data.success){
        setFavorites(response.data.favorites)      
      }
      else{
        alert('영화 정보를 가져오는데 실패했습니다.')
      }
    })
  }

 

원래 useEffect 함수 안에 있던 코드라서 useEffect 안은

  useEffect(() => {
    fetchFavoritedMovie()
  }, [])

이렇게 바뀌었다

 

암튼 다시 돌아가서 onClickDelete 함수를 보면 removeFromFavorite을 만들어줘야 됨을 알 수 있다

server 파일에 있는 favorite.js로 고고

전에 썼던 틀과 비슷하게 구성한다

findOneAndDelete 함수를 이용하여 삭제를 한다

// list에서 삭제
router.post('/removeFromFavorite', (req, res) => {

  Favorite.findOneAndDelete({movieId: req.body.movieId, userFrom: req.body.userFrom})
  .exec((err, result) =>{
    if(err) return res.status(400).send(err)
    return res.status(200).json({success:true, result})
  })
})

그럼 페이지를 가보자

 

 

결과창

클릭 직전
클릭 후
영화 정보 페이지를 들어가도 Add to Favorite 0으로 뜬다

 

 

댓글