👀 SPA(Single Page Application)
👣 라이브러리 or 프레임워크 사용해 뷰 렌더링을 사용자의 브라우저가 담당하도록 함
👣 애플리케이션을 브라우저에 불러와서 실행 ➡️ 사용자와의 인터랙션 발생하면 필요한 부분만 자바스트립트 사용하여 업데이트
👣 새로운 데이터 필요하면 서버 API 호출하여 필요한 데이터만 새로 불러와 애플리케이션에서 사용
👣 서버에서 사용자에게 제공하는 페이지는 한 종류
👣 해당 페이지에서 로딩된 자바스트립트와 현재 사용자 브라우저의 주소 상태에 따라 다양한 화면 보여줄 수 있음
👣 SPA 단점
🟠 앱의 규모가 커지면 자바스트립트 파일이 너무 커짐 ➡️ 코드 스플리팅(code spliting) 사용해 개선
🟠 브라우저에서 자바스크립트를 사용하여 라우팅 관리하는 것 ➡️ 자바스크립트를 실행하지 않는 일반 크롤러에서는 페이지의 정보를 제대로 수집 못함 ➡️ 서버 사이드 렌더링(server-side rendering)으로 해결
$ yarn create react-app router-tutorial
$ cd router-tutorial
$ yarn add react-router-dom
👣 프로젝트에 라우터 적용: src/index.js 파일에서 react-router-dom에 내장되어 있는 BrowserRouter 컴포넌트 사용해 감싸면 됨.
👣 BrowserRouter 컴포넌트: 웹 애플리케이션에 HTML5의 History API를 사용해 페이지를 새로고침하지 않고도 주소를 변경하고, 현재 주소에 관련된 정보를 props로 쉽게 조회하거나 사용할 수 있도록 해줌
//Home.js
const Home = () => {
return (
<div>
<h1>홈</h1>
<p>홈, 그 페이지는 가장 먼저 보여지는 페이지.</p>
</div>
);
};
export default Home;
//About.js
const About = ({ location }) => {
return (
<div>
<h1>소개</h1>
<p>이 프로젝트는 리액트 라우터 기초를 실습해 보는 예제 프로젝트입니다.</p>
</div>
);
};
export default About;
👣 Route 컴포넌트 : 어떤 규칙을 가진 경로에 어떤 컴포넌트를 보여 줄지 정의할 수 있음
<Route path="주소규칙" component={보여 줄 컴포넌트} />
👣 Link 컴포넌트 : 클릭하면 다른 주소로 이동시켜 주는 컴포넌트
👣 a 태그 : 페이지를 전환하는 과정에서 페이지를 새로 불러오기 때문에 애플리케이션이 들고 있던 상태들을 모두 날림
👣 Link 컴포넌트 사용해 페이지 전환 : 페이지를 새로 불러오지 않고 애플리케이션은 그대로 유지한 상태에서 HTML5 History API 사용해 페이지의 주소만 변경
<Link to="주소">내용</Link>
//App.js
(...)
<Route path={['/about', '/info']} component={About} />
(...)
👀 유동적인 값 전달
👣 파라미터 : 특정 아이디 or 이름을 사용하여 조회할 때 사용
👣 쿼리 : 키워드 검색 or 페이지에 필요한 옵션 전달 시 사용
//Profile.js
const data = {
velopert: {
name: "김민준",
description: "리액트를 좋아하는 개발자",
},
gildong: {
name: "홍길동",
description: "고전 소설 홍길동전의 주인공",
},
};
const Profile = ({ match }) => {
const { username } = match.params;
const profile = data[username];
if (!profile) {
return <div>존재하지 않는 사용자입니다.</div>;
}
return (
<div>
<h3>
{username}({profile.name})
</h3>
<p>{profile.description}</p>
</div>
);
};
export default Profile;
👣 match 객체 안에는 현재 컴포넌트가 어떤 경로 규칙에 의해 보이는지에 대한 정보 들어있음
//App.js
import { Route, Link, Switch } from "react-router-dom";
import About from "./About";
import Home from "./Home";
import Profiles from "./Profiles";
(...)
<li>
<Link to="/profile/velopert">velopert프로필</Link>
</li>
<li>
<Link to="/profile/gildong">gildong프로필</Link>
</li>
</ul>
<hr />
<Route path="/" component={Home} exact={true} />
<Route path={["/about", "/info"]} component={About} />
<Route path="/profile/:username" component={Profile} />
(...)
👣 쿼리 : location 객체에 들어 있는 search 값에서 조회할 수 있음
👣 location 객체 : 라우트로 사용된 컴포넌트에게 props로 전달되며, 웹 애플리케이션의 현재 주소에 대한 정보 지님
👣 search 값에서 특정 값을 읽어 오기 위해서는 이 문자열을 객체 형태로 변환해 주어야 함
👣 쿼리 문자열을 객체로 파싱하는 과정에서 결과 값은 언제나 문자열
👣 서브 라우트 : 라우트 내부에 또 라우트를 정의하는 것
//Profiles.js
import { NavLink, Route } from "react-router-dom";
import Profile from "./Profile";
const Profiles = () => {
return (
<div>
<h3>사용자 목록:</h3>
<ul>
<li>
<NavLink to="/profiles/velopert">
velopert
</NavLink>
</li>
<li>
<NavLink to="/profiles/gildong">
gildong
</NavLink>
</li>
</ul>
<Route
path="/profiles"
exact
render={() => <div>사용자를 선택해 주세요.</div>}
/>
<Route path="/profiles/:username" component={Profile} />
</div>
);
};
export default Profiles;
👀 history 객체
👣 라우트로 사용된 컴포넌트에 match, location과 함께 전달되는 props 중 하나
👣 이 객체를 통해 컴포넌트 내에 구현하는 메소드에서 라우터 API 호출
👀withRouter 함수
👣 HoC(Higher-order Component)
👣 라우트로 사용된 컴포넌트가 아니어도 match, location, history 객체 접근할 수 있게 해줌
👣 withRouter 사용할 때는 컴포넌트를 내보내 줄 때 함수로 감싸 줌
👀 Switch 컴포넌트
👣 여러 Route를 감싸서 그 중 일치하는 단 하나의 라우트만을 렌더링
👣 Switch 사용해 모든 규칙과 일치하지 않을 때 보여 줄 Not Found 페이지 구현할 수 있음
👀 NavLink 컴포넌트
👣 현재 경로와 Link에서 사용하는 경로가 일치하는 경우 특정 스타일 or CSS 클래스 적용할 수 있는 컴포넌트
👣 링크 활성화되었을 때의 스타일 적용할 때 : activeStyle을 props로
👣 링크 활성화되었을 때의 CSS 클래스를 적용할 때 : activeClassName 값을 props로