#8 영화 출연진들 가져오기
전에 #5에서 배웠던 Grid를 이용하여 영화 출연진도 똑같은 형태로 출력되게 할 것이다
Toggle Actor View를 누르면 영화 출연진이 나오는 구조이다
저번 #7 때 MovieDetail.js에서 endpointCrew라는 변수를 선언한 적이 있다
let endpointCrew = `${API_URL}movie/${movieId}/credits?api_key=${API_KEY}` // 영화 출연진 정보 가져옴
그럼 fetch 구문을 이용하여 영화 출연진들을 가져와보고, 이를 console.log로 찍어보자
fetch(endpointCrew)
.then(response => response.json())
.then(response =>{
console.log('responseForCrew', response)
})
여기서 우리가 쓸 정보는 cast의 name, profile_path이다
useState를 사용하여 배우들의 정보를 받는다
const [Casts, setCasts] = useState([]) // array로 받는다는 뜻
그리고 기본적인 형태는 전에 했던 #5 Grid 편과 동일하므로 LandingPage.js에서
{/*Movie Grid Cards*/}
<Row gutter={[16, 16]}>
{Movies && Movies.map((movie, index) => (
<React.Fragment key={index}>
<GridCards
image={movie.poster_path ? `${IMAGE_BASE_URL}w500${movie.poster_path}` : null}
movieId={movie.id} // 고유의 영화 정보에 들어가기 위해 필요
movieName={movie.original_title}
/>
</React.Fragment>
))}
</Row>
이 부분을 복사하여
MovieDetail.js의 {/*Actors Grid*/}에 붙여 넣는다
그 다음 수정을 한다
{/*Actors Grid*/}
<div style={ {display:'flex', justifyContent:'center', margin:'2rem'} }>
<button >Toggle Actor View</button>
</div>
<Row gutter={[16, 16]}>
{Casts && Casts.map((cast, index) => (
<React.Fragment key={index}>
<GridCards
image={cast.profile_path ? `${IMAGE_BASE_URL}w500${cast.profile_path}` : null}
characterName={cast.name}
/>
</React.Fragment>
))}
</Row>
이 때 GridCards.js, Row가 필요하므로 import도 잊지 않는다
import GridCards from '../commons/GridCards'
import { Row } from 'antd'
아까 GridCards의 기본적인 틀을 쓴다고 했었다
근데 쓰이는 경우가 두가지가 있다
1. LandingPage, 2. Toggle Actor View
그러므로 구분을 하여 출력을 해줘야 한다
LandingPage.js로 가서 <GridCards> 내부 제일 첫번째 줄에 코드 하나를 추가한다
<GridCards
landingPage
image={movie.poster_path ? `${IMAGE_BASE_URL}w500${movie.poster_path}` : null}
movieId={movie.id} // 고유의 영화 정보에 들어가기 위해 필요
movieName={movie.original_title}
/>
landingPage라는 코드를 추가해준 모습이다
다시 GridCards.js로 가서 코드를 수정해준다
function GridCards(props) {
// columm의 size가 24이므로 lg일 땐 4개, md일 땐 3개, xs일 땐 1개만 보인다
if(props.landingPage){
return (
<Col lg={6} md={8} xs={24}>
<div style={{position: 'relative'}}>
<a href={`/movie/${props.movieId}`}>
<img style={{width:'100%', height: '320px'}} src={props.image} alt={props.movieName} />
</a>
</div>
</Col>
)
}
else{
return(
<Col lg={6} md={8} xs={24}>
<div style={{position: 'relative'}}>
<img style={{width:'100%', height: '320px'}} src={props.image} alt={props.characterName} />
</div>
</Col>
)
}
}
<a>태그(하이퍼링크 연결)를 없애주고 alt에 있는 이름도 characterName으로 바꿔준다
landingPage면 if문이, 그 이외는 else문이 실행된다
그렇게 하고 창을 보면
잘 뜨는 것을 확인할 수 있다
하지만 우리가 원하는 것은 Toggle Actor View를 눌렀을 때만 배우 사진들이 보이는 것이다
그러므로 그에 대한 설정을 해준다
일단 useState를 이용하여 아래와 같은 코드를 MovieDetail.js에 적어준다
const [ActorToggle, setActorToggle] = useState(false)
Toggle Actor View를 클릭해야 이벤트가 발생하므로
<button onClick={toggleActorView}>Toggle Actor View</button>
위와 같이 적어준다
클릭하면 toggleActorView라는 event가 발생하는 것이므로 toggleActorView를 정의해준다
const toggleActorView = () => {
setActorToggle(!ActorToggle)
}
초기값이 false였으므로 !연산자를 붙이면 true가 될 것이다
그럼 아까 설정해준 Grid들이 ActorToggle이 true인 경우에만 나타나게 설정하면 된다
{/*Actors Grid*/}
<div style={ {display:'flex', justifyContent:'center', margin:'2rem'} }>
<button onClick={toggleActorView}>Toggle Actor View</button>
</div>
{ActorToggle &&
<Row gutter={[16, 16]}>
{Casts && Casts.map((cast, index) => (
<React.Fragment key={index}>
<GridCards
image={cast.profile_path ? `${IMAGE_BASE_URL}w500${cast.profile_path}` : null}
characterName={cast.name}
/>
</React.Fragment>
))}
</Row>
}
결과창
근데 가끔씩 에러가 뜨면서 사진이 안뜨는 경우가 있었다
그래서 profile_path가 null이면 아예 출력을 하지 않게 코드를 다시 구성해보았다
MovieDetail.js을 수정해준다
const [LoadingForCasts, setLoadingForCasts] = useState(true)
fetch구문이 있었는데 거기에 setLoadingForCasts를 추가한다
useEffect(() => {
// cast정보만 가져올것(crew엔 감독도 있기 때문)
let endpointCrew = `${API_URL}movie/${movieId}/credits?api_key=${API_KEY}` // 영화 출연진 정보 가져옴
let endpointInfo = `${API_URL}movie/${movieId}?api_key=${API_KEY}`
//console.log(props.match)
fetch(endpointInfo)
.then(response => response.json())
.then(response =>{
//console.log(response)
setMovie(response)
})
fetch(endpointCrew)
.then(response => response.json())
.then(response =>{
console.log('responseForCrew', response)
setCasts(response.cast)
})
setLoadingForCasts(false)
} , [])
맨 아래에 setLoadingForCasts(false)가 추가된 것을 볼 수 있다
그리고 {/*Actors Grid*/}부분을 수정해준다
{ActorToggle &&
<Row gutter={[16, 16]}>
{!LoadingForCasts ? Casts.map((cast, index) => (
cast.profile_path &&
//<React.Fragment key={index}>
<GridCards
image={cast.profile_path ? `${IMAGE_BASE_URL}w500${cast.profile_path}` : null}
characterName={cast.name}
/>
//</React.Fragment>
)):
<div>loading...</div>
}
</Row>
}
Loading이 되어야 GridCard를 출력하게 만들었다
'REACT' 카테고리의 다른 글
[클론코딩] 무비앱 시리즈 #10 ~ #11 (0) | 2022.07.20 |
---|---|
[클론코딩] 무비앱 시리즈 #9 (0) | 2022.07.19 |
[클론코딩] 무비앱 시리즈 #7 (0) | 2022.07.13 |
[클론코딩] 무비앱 시리즈 #6 (0) | 2022.07.13 |
[클론코딩] 무비앱 시리즈 #5 (0) | 2022.07.12 |
댓글