For Programmer

10. Favorite 페이지 만들기 - 영화 사이트 만들기 본문

React & Node.js 프로젝트/영화사이트 만들기

10. Favorite 페이지 만들기 - 영화 사이트 만들기

유지광이 2020. 7. 29. 22:33
728x90

1.Favorite페이지만들기(components-views-FavoritePage-FavoritePage.js)

2..Favorite 페이지를 App.js에서 라우터로 등록하기

<Route exact path="/favorite" component={Auth(FavoritePage, true)} />

3.MongDB에서 Favorite으로 된 영화 정보를 가져오기(Axios통신)(FavoritePage.js)

function FavoritePage() {
  const [Favorites, setFavorites] = useState([]);

  const fetchFavoredMovie = () => {
    //좋아요 영화들을 서버로부터 로드하는 API
    Axios.post('/api/favorite/getFavoredMovie', {
      userFrom: localStorage.getItem('userId'),
    }).then((response) => {
      if (response.data.success) {
        console.log(response.data.favorites);
        setFavorites(response.data.favorites);
      } else {
        alert('영화 정보를 가져오는데 실패 했습니다.');
      }
    });
  };

  useEffect(() => {
    fetchFavoredMovie();
  }, []);
  
  const renderCards = Favorites.map((favorite, index) => {
    return (
      <tr key={index}>
        <td>{favorite.movieRunTime} mins</td>
        <td>
          <Button>
            Remove
          </Button>
        </td>
      </tr>
    );
  });
  return (
    <div style={{ width: '85%', margin: '3rem auto' }}>
      <h2> Favorite Movies</h2>
      <hr />

      <table>
        <thead>
          <tr>
            <th>Movie Title</th>
            <th>Movie RunTime</th>
            <td>Remove from favorites</td>
          </tr>
        </thead>
        <tbody>{renderCards}</tbody>
      </table>
    </div>
  );
}

*위의 테이블을 꾸미기 위한 CSS

table {
  font-family: Arial, Helvetica, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #dddddd;
}

4.Axios통신을 통해 영화 정보를 제공하는 API를 서버 라우터에 만들기(server-routes-favorites.js)

router.post('/getFavoredMovie', (req, res) => {
  Favorite.find({ userFrom: req.body.userFrom }).exec((err, favorites) => {
    if (err) return res.status(400).send(err);
    return res.status(200).json({ success: true, favorites });
  });
});

5.마우스를 갖다대면 해당 영화의 이미지를 나오게하기(FavoritePage.js)

import { Popover, Button } from 'antd';

*antd 에서 Popover API를 가져온다.

const renderCards = Favorites.map((favorite, index) => {
    const content = (
      <div>
        {favorite.moviePost ? (
          <img src={`${IMAGE_BASE_URL}w500/${favorite.moviePost}`} /> //이미지 가져오는 API
        ) : (
          '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>
    );
  });
  return (
    <div style={{ width: '85%', margin: '3rem auto' }}>
      <h2> Favorite Movies</h2>
      <hr />

      <table>
        <thead>
          <tr>
            <th>Movie Title</th>
            <th>Movie RunTime</th>
            <td>Remove from favorites</td>
          </tr>
        </thead>
        <tbody>{renderCards}</tbody>
      </table>
    </div>
  );
}

6.Remove 버튼 이벤트 만들기(FavoritePage.js)

 <td>
          <Button
            onClick={() => onClickDelete(favorite.movieId, favorite.userFrom)}
          >
            {/*이렇게 화살표함수로 onClikeDelete메소드에 파라미터를 보낼수있다. */}
            {/*그냥 onClickDelete 할경우 함수가 그대로 표시가된다. 그러나 return으로 위와같이
            표시하게 될경우 함수를 실행하게끔 할 수있다. */}
            Remove
          </Button>
        </td>

*버튼에 이벤트를 주는데 onClickDelete 함수에 인자를 전달해야 하기때문에 기존에 사용하던 방식인 onClick={onClickDelete} 가 아닌 화살표 함수를 만들어 클릭할경우 해당함수에 인자를전달할 수 있도록 실행하는 방식으로 만들어야한다. 

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

    Axios.post('/api/favorite/removeFromFavorite', variables).then(
      (response) => {
        if (response.data.success) {
          //결과값을 제대로 가지고왔으면 다시한번 좋아요리스트 영화들을 로드한다.
          fetchFavoredMovie();
        } else {
          alert('리스트에서 지우는데 실패했습니다.');
        }
      }
    );
  };

*위 코드에서 fetchFavoredMovie 함수는 다음과같다.

const [Favorites, setFavorites] = useState([]);

  const fetchFavoredMovie = () => {
    //좋아요 영화들을 서버로부터 로드하는 API
    Axios.post('/api/favorite/getFavoredMovie', {
      userFrom: localStorage.getItem('userId'),
    }).then((response) => {
      if (response.data.success) {
        console.log(response.data.favorites);
        setFavorites(response.data.favorites);
      } else {
        alert('영화 정보를 가져오는데 실패 했습니다.');
      }
    });
  };

 

FavoritePage.js 의 전체코드

import React, { useEffect, useState } from 'react';
import './favorite.css';
import Axios from 'axios';
import { Popover, Button } from 'antd';
import { IMAGE_BASE_URL } from '../../Config';

function FavoritePage() {
  const [Favorites, setFavorites] = useState([]);

  const fetchFavoredMovie = () => {
    //좋아요 영화들을 서버로부터 로드하는 API
    Axios.post('/api/favorite/getFavoredMovie', {
      userFrom: localStorage.getItem('userId'),
    }).then((response) => {
      if (response.data.success) {
        console.log(response.data.favorites);
        setFavorites(response.data.favorites);
      } else {
        alert('영화 정보를 가져오는데 실패 했습니다.');
      }
    });
  };

  useEffect(() => {
    fetchFavoredMovie();
  }, []);

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

    Axios.post('/api/favorite/removeFromFavorite', variables).then(
      (response) => {
        if (response.data.success) {
          //결과값을 제대로 가지고왔으면 다시한번 좋아요리스트 영화들을 로드한다.
          fetchFavoredMovie();
        } else {
          alert('리스트에서 지우는데 실패했습니다.');
        }
      }
    );
  };

  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
            onClick={() => onClickDelete(favorite.movieId, favorite.userFrom)}
          >
            {/*이렇게 화살표함수로 onClikeDelete메소드에 파라미터를 보낼수있다. */}
            {/*그냥 onClickDelete 할경우 함수가 그대로 표시가된다. 그러나 return으로 위와같이
            표시하게 될경우 함수를 실행하게끔 할 수있다. */}
            Remove
          </Button>
        </td>
      </tr>
    );
  });
  return (
    <div style={{ width: '85%', margin: '3rem auto' }}>
      <h2> Favorite Movies</h2>
      <hr />

      <table>
        <thead>
          <tr>
            <th>Movie Title</th>
            <th>Movie RunTime</th>
            <td>Remove from favorites</td>
          </tr>
        </thead>
        <tbody>{renderCards}</tbody>
      </table>
    </div>
  );
}

export default FavoritePage;

*실행결과

 

동영상강의

 

728x90
Comments