니꼬의 뽀나스 강의
조금 심심한 페이지를 react를 이용하여 좀 더 꾸며보자.
navigation바를 만들기위해 react-router-dom 을 이용하자.
npm install react-router-dom
파일들을 위 사진처럼 정리하자.
App.js에 있는 내용들을 모두 Home.js로 옮기고 App.css를 Home.css로 변경
경로를 위와 같이 변경 후 아래를 작성하자.
App.js
import React from "react";
import { HashRouter, Route } from "react-router-dom";
import About from "./routes/About";
function App() {
return (
<HashRouter>
<Router path="/about" component={About} />
</HashRouter>
);
}
export default App;
<Router path="/about" component={About} />
path라면 About component를 보여줘라는 의미이다.
About.js
import React from "react";
function About(){
return <span>About this page: I built it beacause I love movies.</span>
}
export default About;
이런식으로 새로운 페이지를 작성할 수 있다.
주소에 생긴 #은 hash router를 이용해서 생긴것 같다.
이와 같이 아까 옮겨준 home.js도 적용해보면 아래와 같은 문제점이 생긴다.
About과 Home이 겹치는 상황이다.
Router가 작동하는 방식 때문에 위와 같은 현상이 나타난다.
path가 "/"이면 "/" 인것만 찾지만 paht가 "/About"일때에는 "/"이걸 먼저 찾고 그다음 "About"을 찾아 둘 다 렌더링 되어 버리기 때문이다.
이를 위해 exact를 이용하면 위와 같은 현상을 방지할 수 있다.
App.js
import React from "react";
import { HashRouter, Route } from "react-router-dom";
import Home from "./routes/Home";
import About from "./routes/About";
import Navigation from "./components/Navigation";
import "./App.css";
function App() {
return (
<HashRouter>
<Navigation />
<Route path="/" exact={true} component={Home} />
<Route path="/about" component={About} />
</HashRouter>
);
}
export default App;
Navigation.js
import React from "react";
import { Link } from "react-router-dom";
function Navigation() {
return (
<div>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</div>
);
}
export default Navigation;
Link 대신 a 태그를 이용할 수도 있지만, a 태그는 링크를 클릭했을 때, 페이지 전체가 새로고침 되어버린다. 페이지에 내용이 많으면 그만큼 비효율적이게 된다는 뜻이다. 이를 해결하기위한 react-router-dom 안의 Link를 이용하면 된다.
그러면 새로고침이 아닌 해당 path로 다시 렌더링을 하게된다.
위에 것들을 응용하여 영화를 눌렀을 때 그 영화의 세부정보 페이지로 이동하는 동작까지 만들어보자.
Movie.js를 확인해보면 Link를 이용하여 페이지 사이의 정보를 공유하고있다.
pathname:을 이용하여 리다이렉팅을하고 영화의 정보를 넘겨주었다.
import React from "react";
import { Link } from "react-router-dom";
import PropTypes from "prop-types";
import "./Movie.css";
function Movie({ id, year, title, summary, poster, genres }) {
return (
<div className="movie">
<Link
to={{
pathname: `/movie/${id}`,
state: {
year,
title,
summary,
poster,
genres,
},
}}
>
<img src={poster} alt={title} title={title} />
<div className="movie__data">
<h3 className="movie__title">{title}</h3>
<h5 className="movie__year">{year}</h5>
<ul className="movie__genres">
{genres.map((genre, index) => (
<li key={index} className="genres__genre">
{genre}
</li>
))}
</ul>
<p className="movie__summary">{summary.slice(0, 180)}...</p>
</div>
</Link>
</div>
);
}
Movie.propTypes = {
id: PropTypes.number.isRequired,
year: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
summary: PropTypes.string.isRequired,
poster: PropTypes.string.isRequired,
genres: PropTypes.arrayOf(PropTypes.string).isRequired,
};
export default Movie;
상세 코드는 github <- 클릭