일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 숭실대
- 애플 디벨로퍼 아카데미 후기
- 네이버 치지직
- SWIFT
- Swift 기능
- 애플 디벨로퍼 아카데미
- ObservedObject
- Swift 디자인패턴
- 운영체제
- sqoop
- Apple Developer Academy @ POSTECH
- global soop
- 애플 디벨로퍼 아카데미 21주차 회고
- OS
- swift문법
- Swift 문법
- ObservableObject
- 앱 비교 프로젝트
- 데이터베이스
- 제앱소
- apple developer academy 후기
- StateObject
- 데이터베이스 공부
- 애플 아카데미 후기
- 네이버 부스트캠프
- react
- useReducer
- iOS 개발 오류
- 소프트웨어분석및설계
- 치지직
- Today
- Total
사과하는 제라스
13장. 리액트 라우터로 SPA 개발하기 본문
목차
- 라우팅이란?
"사용자가 요청한 URL에 따라 알맞은 페이지를 보여주는 것."
- 라우팅 시스템 라이브러리 종류
1) react-router
2) Next.js
3) react-location, rakkas 등등
- SPA(Single Page Application)이란?
"하나의 페이지로 이루어진 애플리케이션"
-> HTML을 한번만 받아와서 웹 애플리케이션을 실행시킨 후, 이후에는 필요한 데이터만 받아와서 화면에 업데이트하는 것.
- 리액트 라우터 적용 및 기본 사용법
- 기본 사용법
1) <BowserRouter>를 src/index.js 파일에서 감싸주면 됨.
2) <Routes> 컴포넌트 내에 <Route path="addressRule" element={showingComponent JSX} />
로 트리 틀을 잡음.
- 타 페이지로 이동하는 Link 버튼 설정
<Link to="/about">소개</Link>
- URL 파라미터
: useParams라는 Hook을 쓰면 URL 파라미터를 객체 형태로 하여 조회 가능함.
//App.js
import { Route, Routes } from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";
import Profile from "./pages/Profile";
import Articles from "./pages/Articles";
import Article from "./pages/Article";
import Layout from "./Layout";
import NotFound from "./pages/NotFound";
import Login from "./pages/Login";
import MyPage from "./pages/MyPage";
const App = () => {
return (
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/profiles/:username" element={<Profile />} />
</Route>
<Route path="/articles" element={<Articles />}>
<Route path=":id" element={<Article />} />
</Route>
<Route path="/login" element={<Login />} />
<Route path="/mypage" element={<MyPage />} />
<Route path="*" element={<NotFound />} />
</Routes>
);
};
export default App;
import { useParams } from "react-router-dom";
const data = {
xerath: {
name: "윤동주",
descriptiong: "리액트 개발을 하고 싶은 꿈꾸사",
},
gildong: {
name: "홍길동",
description: "고전 소설 홍길돌전의 주인공",
},
};
const Profile = () => {
const params = useParams();
const profile = data[params.username]; //이걸로 key-value 객체에서 원하는 값을 찾는구나!
return (
<div>
<h1>사용자 프로필</h1>
{profile ? (
<div>
<h2>{profile.name}</h2>
<p>{profile.description}</p>
</div>
) : (
<p>존재하지 않는 프로필입니다.</p>
)}
</div>
);
};
export default Profile;
- 쿼리스트링
1. useLocation
: 이걸 쓰면
pathname: 쿼리 스트링을 제외한 현재 주소의 경로
search: 맨 앞의 ? 문자를 포함한 쿼리스트링 값
hash: 주소의 # 문자열 뒤의 값
state: 페이지로 이동할 때 임의로 넣을 수 있는 상태 값
key: location 객체의 고유값. initial key는 default.
import { useLocation } from "react-router-dom";
const About = () => {
const location = useLocation();
return (
<div>
<h1>소개</h1>
<p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
<p>쿼리스트링: {location.search}</p>
</div>
);
};
export default About;
2. useSearchParams
-> params에 대한 useState 기능 같은 거라고 보면 됨.
import { useSearchParams } from "react-router-dom";
const About = () => {
const [searchParams, setSearchParams] = useSearchParams({
mode: 1,
detail: "true",
});
const detail = searchParams.get("detail");
const mode = searchParams.get("mode");
const onToggleDetail = () => {
setSearchParams({ mode, detail: detail === "true" ? false : true });
};
const onToggleMode = () => {
const nextMode = mode === null ? 1 : parseInt(mode) + 1;
setSearchParams({ mode: nextMode, detail });
};
return (
<div>
<h1>소개</h1>
<p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
<p>detail: {detail}</p>
<p>mode: {mode}</p>
<button onClick={onToggleDetail}>Toggle Detail</button>
<button onClick={onToggleMode}>Toggle Mode</button>
</div>
);
};
export default About;
- 중첩된 라우트
1. <Outlet /> 사용 -> 상위 컴포넌트를 가져다가 보여줄 수 있음.
2. 상위 컴포넌트에 element 설정 -><Route> 상위 컴포넌트에서 하위 컴포넌트들에 뿌려줌.
const App = () => {
return (
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/profiles/:username" element={<Profile />} />
</Route>
<Route path="/articles" element={<Articles />}>
<Route path=":id" element={<Article />} /> //이 부분이 Oulet을 통해 나타남.
</Route>
<Route path="/login" element={<Login />} />
<Route path="/mypage" element={<MyPage />} />
<Route path="*" element={<NotFound />} />
</Routes>
);
};
import { Outlet, NavLink } from "react-router-dom";
const Articles = () => {
return (
<div>
<Outlet />
<ul>
<ArticleItem id={1} />
<ArticleItem id={2} />
<ArticleItem id={3} />
</ul>
</div>
);
};
const ArticleItem = ({ id }) => {
const activeStyle = {
color: "green",
fontSize: 21,
};
return (
<li>
<NavLink
style={({ isActive }) => (isActive ? activeStyle : undefined)}
to={`articles/${id}`}
>
게시글 {id}
</NavLink>
</li>
);
};
export default Articles;
- useNavigate
: Link 컴포넌트를 사용하지 않고 다른 페이지로 이동해야 하는 상황에 사용하는 Hook.
import { Outlet, useNavigate } from "react-router-dom";
const Layout = () => {
const navigate = useNavigate();
const goBack = () => {
navigate(-1);
};
const goArticles = () => {
navigate("/articles", { replace: true }); //replace 옵션 사용 시 페이지 이동할 때 현재 페이지를 페이지 기록에 남기지 않음.
};
return (
<div>
<header style={{ background: "lightgray", padding: 16, fontSize: 24 }}>
<button onClick={goBack}>뒤로가기</button>
<button onClick={goArticles}>게시글 목록</button>
</header>
<main>
<Outlet />
</main>
</div>
);
};
export default Layout;
- NavLink
: 링크에서 사용하는 경로가 현재 라우트의 경로와 일치하는 경우 특정 스타일 or CSS클래스를 적용하는 컴포넌트.
isActive를 boolean값으로 전달받음.
import { Outlet, NavLink } from "react-router-dom";
const Articles = () => {
return (
<div>
<Outlet />
<ul>
<ArticleItem id={1} />
<ArticleItem id={2} />
<ArticleItem id={3} />
</ul>
</div>
);
};
const ArticleItem = ({ id }) => {
const activeStyle = {
color: "green",
fontSize: 21,
};
return (
<li>
<NavLink
style={({ isActive }) => (isActive ? activeStyle : undefined)}
to={`articles/${id}`}
>
게시글 {id}
</NavLink>
</li>
);
};
export default Articles;
- *을 이용해서 Not Found 페이지 구현
import { Route, Routes } from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";
import Profile from "./pages/Profile";
import Articles from "./pages/Articles";
import Article from "./pages/Article";
import Layout from "./Layout";
import NotFound from "./pages/NotFound";
import Login from "./pages/Login";
import MyPage from "./pages/MyPage";
const App = () => {
return (
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/profiles/:username" element={<Profile />} />
</Route>
<Route path="/articles" element={<Articles />}>
<Route path=":id" element={<Article />} />
</Route>
<Route path="/login" element={<Login />} />
<Route path="/mypage" element={<MyPage />} />
<Route path="*" element={<NotFound />} /> //이런 식으로 해주면 매칭되지 않는 주소들은 모두 NotFound 컴포넌트를 보여줌.
</Routes>
);
};
export default App;
- Navigate
: 컴포넌트를 화면에 보여주는 순간 다른 페이지로 이동을 하고 싶을 때 사용하는 컴포넌트(페이지를 리다이렉트하고 싶을 때 씀!)
import { Navigate } from "react-router-dom";
const MyPage = () => {
const isLoggedIn = false;
if (!isLoggedIn) {
return <Navigate to="/login" replace={true} />;
}
return <div>마이 페이지</div>;
};
export default MyPage;
'코테이토 동아리 > [코테이토]React 스터디 5기' 카테고리의 다른 글
14장. 외부 API를 연동하여 뉴스 뷰어 만들기 (0) | 2023.02.10 |
---|---|
12장. immer를 사용하여 더 쉽게 불변성 유지하기 (0) | 2023.02.03 |
11장. 컴포넌트 성능 최적화 (0) | 2023.02.03 |
10장. 일정 관리 웹 애플리케이션 만들기 (1) | 2023.01.27 |
9장. 컴포넌트 스타일링 (0) | 2023.01.27 |