React learning #8 Movie App ,Router, Link to
import { getMouseEventOptions } from "@testing-library/user-event/dist/utils";
import { useState, useEffect } from "react";
function App() {
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=9&sort_by=year"
)
).json();
setMovies(json.data.movies);
setLoading(false);
};
useEffect(() => {
getMovies();
}, []);
return (
<div>
{loading ? (
<h1>Loading..</h1>
) : (
<div>
{movies.map((movie) => (
<div key={movie.id}>
<img src={movie.medium_cover_image} alt={movie.title}/>//react에서 img 사용할 때 alt필요
<h2>{movie.title}</h2>
<p>{movie.summary}</p>
<ul>
{movie.genres == null
? ""
: movie.genres.map((g) => (
<li key={g}>{g}</li> //react에서 나열할 때 key 필요
))}
</ul>
</div>
))}
</div>
)}
</div>
);
}
export default App;
Json viewer 확장 설치함
https://chrome.google.com/webstore/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh?hl=ko
JSON Viewer
The most beautiful and customizable JSON/JSONP highlighter that your eyes have ever seen. Open source at https://goo.gl/fmphc7
chrome.google.com
key는 reactjs에서 map을 이용해 render할 때 사용한다.
Movie라는 컴포넌트 만들고 prop설정하기
ReactRouter 페이지전환
https://reactrouter.com/docs/en/v6/getting-started/overview
npm i react-router-dom@5.3.0
import Home from "./routes/Home";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Detail from "./routes/Detail";
// import your route components too
function App() {
return (
<Router>
<Switch> // 한 번에 하나의 페이지만 렌더하기 위해
<Route path="/movie">
<Detail />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Router>
);
}
export default App;
react-router-dom 5버전 -> 버전6 바뀐 부분
1. Switch컴포넌트가 Routes컴포넌트로 대체되었습니다.
Switch -> Routes
2. Route컴포넌트 사이에 자식 컴포넌트를 넣지 않고, element prop에 자식 컴포넌트를 할당하도록 바뀌었습니다.
Route path="/" element={< Home / >}
react-router-dom 6버전 문서
https://reactrouter.com/docs/en/v6/getting-started/overview
<BrowserRouter>
<Routes>
<Route path="/" element={<App />}>
<Route index element={<Home />} />
<Route path="teams" element={<Teams />}>
<Route path=":teamId" element={<Team />} />
<Route path="new" element={<NewTeamForm />} />
<Route index element={<LeagueStandings />} />
</Route>
</Route>
</Routes>
</BrowserRouter>
Link to 네비게이션에서 링크 걸 때 !
평소하던대로 <a href=""></a>로 링크를 걸게되면 새로고침하게된다.
react는 최대한 리렌더링을 안하고하기에
import { Link } from "react-router-dom";
<Link to="/moive"}{title}</Link>
는 페이지를 새로고침하지 않고 넘어가게됨
import { Link } from "react-router-dom";
function Home() {
return (
<div>
<h1>Home</h1>
<nav>
<Link to="/">Home</Link> |{" "}
<Link to="about">About</Link>
</nav>
</div>
);
}
경로 지정이 잘 안되어서 계속 시도하다가
`Route path="/"`
부분은 모든 라우터중에 가장 마지막에 있어야 잘 되는걸 확인 할 수 있었습니다.
Route는 path의 앞부분 부터 일치하는 부분이 있으면 그걸로 OK합니다.
즉, "/ " 는 "/movie" 의 부분집합 이므로 "/"가 앞쪽에 있으면 "/movie"로 못 넘어갑니다.
그럼에도 불구하고 앞쪽에다 하는걸 고집하신다면
`Route exact path="/"` 처럼 중간에 exact를 넣으면 완전일치로 판정이 바뀌므로 순서에 상관없이 잘 되는 것을 확인 하실 수 있을 겁니다.
https://github.com/UHyun-K/react-for-beginner/commit/dde883ce0f4dfdf304644e4f0fafc83e0a2655b3
React Router · UHyun-K/react-for-beginner@dde883c
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
github.com
import { useState, useEffect } from "react";
import Movie from "../components/Movie.js";
function Home() {
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=9&sort_by=year"
)
).json();
setMovies(json.data.movies);
setLoading(false);
};
useEffect(() => {
getMovies();
}, []);
return (
<div>
{loading ? (
<h1>Loading..</h1>
) : (
<div>
{movies.map((movie) => (
<Movie
key={movie.id}
coverImg={movie.medium_cover_image}
title={movie.title}
summary={movie.summary}
genres={movie.genres}
/>
))}
</div>
)}
</div>
);
}
export default Home;
Movie
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
function Movie({ coverImg, title, summary, genres }) {
return (
<div>
<img src={coverImg} alt={title} />
<h2>
<Link to="/movie">{title}</Link>
</h2>
<p>{summary}</p>
<ul>
{genres == null ? "" : genres.map((g) => <li key={g}>{g}</li>)}
</ul>
</div>
);
}
Movie.propTypes = {
coverImg: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
summary: PropTypes.string.isRequired,
genres: PropTypes.arrayOf(PropTypes.string),
};
App
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
function App() {
return (
<Router>
<Switch>
<Route path="/movie">
<Detail />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Router>
);
}