티스토리 뷰
이전에는 단일 페이지에 관해서 작업하는 일을 했다면 이번에는 어떻게 페이지를 여러개 만들고 전환하는 지에 대해서 배워보자.
- 영화 API를 통해서 영화정보를 가져온다. (쿼리를 통해서 원하는 정보만 가져오기)
- ?minimum_rating=8.5&sort_by=year //쿼리 스트링: 별점이 8.5이상인 영화 + sort year(연도별로 정렬) 가장 최신의 영화를 먼저 보이게
- API 로딩이 끝나면 영화들을 보여준다.
Movie.js
import { useEffect, useState } from 'react';
function Movie() {
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(
`https:yts.mx/api/v2/list_movies.json?minimum_rating=8.5&sort_by=year`,
)
.then((response) => response.json())
.then((json) => console.log(json));
}, []);
return <div>{loading ? <h1>Loading...</h1> : null}</div>;
}
export default Movie;
해당 코드를 실행시켜보면 state를 사용하고 있지 않기 때문에 화면에는 Loading...만 보이지만 콘솔창에는 객체하나가 들어와있을 것이다. 해당 객체를 보면 내가 원하는 정보가 들어와 있음을 확인할 수 있다.
그 다음은 state를 만들어서 원하는 객체를 받아온다.
const [movies, setMovies] = useState([]);
useEffect(() => {
fetch(
`https:yts.mx/api/v2/list_movies.json?minimum_rating=8.5&sort_by=year`
)
.then((response) => response.json())
.then((json) => {
setMovies(json.data.movies);
setLoading(false);
});
}, []);
- 기본값은 빈배열로 주며 console.log를 통해서 잘 작동하고 있는 지 확인해본다.
- 중요) API 로딩이 끝나면 setLoading을 false로 만들어줘야 한다.
+ API를 가져올 때 .then() 보다는 요즘 보편적으로 사용하는 것이 있는데 바로 async-await 이다.
async-await 예제
const getMovies = async () => {
const response = await fetch(
`https:yts.mx/api/v2/list_movies.json?minimum_rating=8.5&sort_by=year`,
);
const json = await response.json();
setMovies(json.data.movies);
setLoading(false);
};
useEffect(() => {
getMovies();
}, []);
async-await short cut
const json = await (
await fetch(
`https:yts.mx/api/v2/list_movies.json?minimum_rating=8.5&sort_by=year`,
)
).json();
setMovies(json.data.movies);
setLoading(false);
};
useEffect(() => {
getMovies();
}, []);
다시 본론으로 돌아와서 제대로 돌아가는 지 확인해보면 console에 처음에는 [] 빈배열이다가 객체가 2번 출력되는 것을 볼 수 있는데 그 이유는 setMovies(), setLoading()을 했기 때문에 객체가 2번 출력된 것이다.
이제 받은 정보들을 화면에 표시하기 위해 map()을 사용한다.
import { useEffect, useState } from 'react';
function Movie() {
const [loading, setLoading] = useState(true);
const [movies, setMovies] = useState([]);
const getMovies = async () => {
const json = await (
await fetch(
`https:yts.mx/api/v2/list_movies.json?minimum_rating=8.5&sort_by=year`,
)
).json();
setMovies(json.data.movies);
setLoading(false);
};
useEffect(() => {
getMovies();
}, []);
console.log(movies);
return (
<div>
{loading ? (
<h1>Loading...</h1>
) : (
<div>
{movies.map((movie) => (
<div key={movie.id}>
<img src={movie.medium_cover_image} />
<h2>{movie.title}</h2>
<p>{movie.summary}</p>
<ul>
{movie.genres.map((g) => (
<li key={g}>{g}</li>
))}
</ul>
</div>
))}
</div>
)}
</div>
);
}
export default Movie;
코드 설명: loading 되었을 때, setLoading을 false로 바꿔주고 맨 처음 moives는 [] 빈배열, 여기에 movies를 받아오면 API로부터 얻은 data로 State를 변경한다. setMovies(json.data.movies); setLoading(false); 이 부분, 그 뒤에 movies.map을 하고 각각의 movie에 접근해서 그 값을 변환할 수 있게 된다. 이를 통해서 화면에 받아온 데이터를 표시한다.
- 보면 map()은 고유값인 key를 주는 것이 꼭 필요하고 영화의 장르를 넣어주려고 봤더니 genres 로 배열이 들어가 있다. 그렇다면 한번 더 map()을 해야한다. map을 할 때 key값은 꼭 줘야하는데 여기서는 배열의 아이템 자체가 고유값이기 때문에 key로 아이템을 줘도 된다. // {movie.genres.map((g) => (<li key={g}>{g}</li>))}
- img 태그를 이용해서 이미지를 로드할 수도 있다. 객체를 보면 사이즈 별로 이미지가 있는 것을 볼 수 있는데 e.g.) small/medium/large_cover_image 이미지 src 값으로 {movie.medium_cover_image} 하면 된다.
-> state로 받은 data를 화면으로 보여주는 것을 완료했다. 그리고 state는 해당 data를 API로부터 받아온 것이다.
'Frontend > react.js' 카테고리의 다른 글
[React JS] 리액트 어플리케이션 배포하기 (with gh-pages) (0) | 2022.03.24 |
---|---|
[React JS] 영화 어플리케이션2(React Router 사용하기) (0) | 2022.03.22 |
[React JS] Coin Tracker만들기 (0) | 2022.03.21 |
[React JS] To Do List 만들기 (0) | 2022.03.18 |
[React JS]useEffect hook로 컴포넌트 제어하기 (0) | 2022.03.17 |
- Total
- Today
- Yesterday
- 원티드 3월 프론트엔드 챌린지
- 타입스크립트 DT
- text input pattern
- aspect-ratio
- 프리렌더링확인법
- getServerSideProps
- fs모듈 넥스트
- ~ ^
- 프리온보딩 프론트엔드 챌린지 3월
- D 플래그
- tilde caret
- grid flex
- nvm경로 오류
- nvm 설치순서
- is()
- 부트캠프항해
- && 셸 명령어
- 항해99추천비추천
- 원티드 프리온보딩 프론트엔드 챌린지 3일차
- getStaticPaths
- 형제 요소 선택자
- reactAPI
- 틸드와 캐럿
- float 레이아웃
- Prittier
- 원티드 FE 프리온보딩 챌린지
- 항해99프론트후기
- 원티드 프리온보딩 FE 챌린지
- 타입스크립트 장점
- 항해99프론트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |