📌 async - await
fetch로 api에 접속하는 방식 중에 then을 이용하여 response를 받아오곤 했는데, async-await를 이용하는 것이 더 보편적이라고 한다.
- then
useEffect(() => {
fetch(
`https://yts.mx/api/v2/list_movies.json?minimum_rating=9&sort_by=year`
)
.then((response) => response.json())
.then((json) => {
setMovies(json.data.movies);
setLoading(false);
});
}, []);
- async - await
const getMovies = async () => {
const json = await (
await fetch(
`https://yts.mx/api/v2/list_movies.json?minimum_rating=9&sort_by=year`
)
).json();
setMovies(json.data.movies);
setLoading(false);
};
useEffect(() => {
getMovies();
}, []);
자바스크립트는 동기식 언어 즉, 한 번에 여러 일들이 동시에 일어난다.
그렇다보니, A라는 일이 처리가 되어야만 B를 처리할 수 있을 때, 위처럼 async-await를 사용하여 비동기적으로 처리가 가능하다.
📌 React Router
- 설치
npm i react-router-dom
- 설정
import React from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Home from "./routes/Home";
import Detail from "./routes/Detail";
function App() {
return (
<Router>
<Routes>
<Route path="/movie" element={<Detail />}></Route>
<Route path="/" element={<Home />}></Route>
</Routes>
</Router>
);
}
각 path에 맞는 component를 화면에 띄울 수 있도록 위와 같이 설정한다.
Routes 에서 path에 맞는 Route 하나만 렌더링 한다.
- Route 간 이동
import { Link } from "react-router-dom";
...
<Link to="/movie">{title}</Link>
a 태그로 href 속성을 이용하여 링크를 걸어두게 된다면, 페이지 전체가 재실행되어 이동이 된다.
Link 컴포넌트를 이용하면 재실행 없이 이동이 가능하다.
function Movie({ id, coverImg, title, summary, genres }) {
return (
<div>
<img src={coverImg} alt={title} />
<h2>
**<Link to={`/movie/${id}`}>{title}</Link>**
</h2>
<p>{summary}</p>
<ul>
{genres.map((genre) => (
<li key={genre}>{genre}</li>
))}
</ul>
</div>
);
}
<Route path="/movie/:id" element={<Detail />}></Route>
/movie/ 뒤로 :id를 추가하면 /movie/1 처럼 사용이 가능하다. 반드시 : 를 앞에 붙여주어야 한다.
- 파라미터 읽기
import { useParams } from "react-router-dom";
...
const x = useParams();
console.log(x);
앞서 /movie/:id로 parameter를 설정해주었기에 Object에 담긴 id를 뽑아오기보다, 바로 id를 구하려면 중괄호 안에 id를 담아주면 된다.,
const { id } = useParams();
⁉ React Hook useEffect has a missing dependency 경고 해결
const getMovies = async () => {
const json = await (
await fetch(`https://yts.mx/api/v2/movie_details.json?movie_id=${id}`)
).json();
setMovie(json.data.movie);
console.log(json);
setLoading(false);
};
useEffect(() => {
getMovies();
}, []);
warning이 발생하는 코드
const getMovies = useCallback(async () => {
const json = await (
await fetch(`https://yts.mx/api/v2/movie_details.json?movie_id=${id}`)
).json();
setMovie(json.data.movie);
console.log(json);
setLoading(false);
}, [id]);
useEffect(() => {
getMovies();
}, [getMovies]);
getMovies에 id라는 변수를 사용해주므로 이를 배열에 추가해주어야 경고가 발생하지 않게 된다.
useCallback을 사용하기 이전에는 렌더링이 될 때마다 getMovies가 생성 및 실행된다고 한다.
따라서, useCallback을 사용하여 id가 변할 때만 getMovie 함수가 실행되도록 하여, 불필요한 함수 생성 및 실행을 방지할 수 있다.