728x90
러닝 리엑트을 요약한 내용입니다.
- 페이지 기반 웹사이트의 경우 이전 페이지나, 다음 페이지, 브라우저 주소 등을 사용해서 페이지 이동이 가능하다
- 단일 페이지 웹사이트에서는 페이지 이동 기능이 문제가 된다.
- 한 페이지 안에서 모든 일이 벌어지기 때문에
- 브라우저 방문 기록, 채깔피, 이전페이지, 다음 페이지 등의 기능은 라우팅 솔루션을 사용해야 한다.
- 라우팅은 클라이언트의 요청을 처리할 종말점을 찾는 과정이다.
- 앵귤러, 엠버, 백폰과 달리 리액트는 표준 라우터가 없다.
- 마이클 잭슨, 라이언 플로렌스는 리액트 라우터라는 이름의 라우터를 만들었다.
- 우버, 젠데스크, 페이팔, 비메오 등의 회사가 리액트 라우터를 채택했다.
1.1.1 라우터 사용하기
- 리액트 라우터의 기능을 보여주기 위해 회사 소개, 이벤트, 제품, 고객 지원 메뉴가 있는 전형적인 웹사이트를 SPA 방식으로 만들자.
- [그림 11-1]
- 웹사이트의 사이트맵은 홈페이지, 각 메뉴 항목에 해당하는 섹션을 위한 페이지, 404 Not Found 오류를 처리하기 위한 오류 페이지
- 홈페이지 - http://localhost:3000/
- 회사 소개 - http://localhost:3000/about
- 이벤트 - http://localhost:3000/events
- 제품 - http://localhost:3000/products
- 고객 지원 - http://localhost:3000/contact
- 404 오류 페이지 - - http://localhost:3000/foo-bar
- 홈페이지 - http://localhost:3000/
- 라우터를 사용하면 이 웹사이트 각 섹션에 대한 경로를 설정할 수 있다.
- 각 경로는 브라우저의 주소창에 넣을 수 있는 종말점을 뜻한다.
- 요청 받은 경로에 따라 적적한 콘텐츠를 렌더링해 보여준다.
- 리액트 라우터와 리액트 라우터 DOM을 설치하자.
- 2021년 06월 기준 6.0이 개발중이라 6.0을 사용하기 위해서는 @next 를 지정해야한다.
npm install react-router@next react-router-dom@next # router-dom에서 history 가 없다고 오류 발생 npm install --save history
- 각 페이지에 해당하는 내용을 담은 컴포넌트를 만들자
- pages.js
import React from "react"; export function Home() { return ( <div> <h1>[홈페이지]</h1> </div> ) } export function About() { return ( <div> <h1>[회사소개]</h1> </div> ) } export function Events() { return ( <div> <h1>[이벤트]</h1> </div> ) } export function Products() { return ( <div> <h1>[제품]</h1> </div> ) } export function Contact() { return ( <div> <h1>[고객지원]</h1> </div> ) }
- index.js 파일에서 App 컴포넌트를 렌더링하는 대신 Router 컴포넌트를 렌더링한다.
- import React from "react"; import { render } from "react-dom"; import App from "./App"; import { BrowserRouter as Router } from "react-router-dom"; render( <Router> <App /> </Router>, document.getElementById("root") )
- App.js 파일 수정
- http://localhost:3000/contact 요청시 페이지가 고객지원으로 잘 나오는지 확인
import React from "react"; import { Routes, Route } from "react-router-dom"; import { Home, About, Events, Products, Contact } from "./pages" function App() { return ( <div> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/events" element={<Events />} /> <Route path="/products" element={<Products />} /> <Route path="/contact" element={<Contact />} /> </Routes> </div> ) } export default App
- 브라우저 링크를 만들어주는 Link라는 컴포넌트를 사용해 네이게이션 메뉴를 만들어보자.
- 링크를 클릭하고 페이지가 잘 이동하는지 확인
import React from "react"; import { Link } from "react-router-dom"; export function Home() { return ( <div> <h1>[회사 웹사이트]</h1> <nav> <Link to="about">회사소개</Link> <Link to="events">이벤트</Link> <Link to="products">제품</Link> <Link to="contact">고객 지원</Link> </nav> </div> ) } export function About() { return ( <div> <h1>[회사소개]</h1> </div> ) } export function Events() { return ( <div> <h1>[이벤트]</h1> </div> ) } export function Products() { return ( <div> <h1>[제품]</h1> </div> ) } export function Contact() { return ( <div> <h1>[고객지원]</h1> </div> ) }
11.2 라우터 프로퍼티
- 리액트 라우터는 렌더링하는 컴포넌트에게 프로퍼티를 넘긴다.
- 현재 위치(주소)를 프로퍼티에서 얻을 수 있다.
- 404 Not Found 오류를 처리하기 위해 현재 위치 정보를 사용하자
- *를 path값으로 사용하고 Whoops404 컴포넌트를 렌더링 하자.
import React from "react"; import { Routes, Route } from "react-router-dom"; import { Home, About, Events, Products, Contact, Whoops404 } from "./pages" function App() { return ( <div> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/events" element={<Events />} /> <Route path="/products" element={<Products />} /> <Route path="/contact" element={<Contact />} /> <Route path="*" element={<Whoops404 />} /> </Routes> </div> ) } export default App
- http://localhost:3000/ddd 호출시 Whoops404 컴포넌트를 렌더링 되는 것을 확인하자
- export function Whoops404() { return ( <div> <h1>Resource not found</h1> </div> ) }
- location 값을 통해 우리가 방문했던 경로의 값을 표시할 수도 있다.
- location.pathname을 사용해 현재 방문중인 경로를 표시하자
- import React from "react"; import { Link, useLocation } from "react-router-dom"; export function Whoops404() { let location = useLocation(); console.log(location); return ( <div> <h1>Resource not found at {location.pathname}</h1> </div> ) }
- Router를 단 한번만 사용해야 하며, 라우팅에서 사용할 모든 컴포넌트를 Router로 감싸야한다.
- 모든 Route 컴포넌트를 Routes 컴포넌트로 감싸야 한다.
- Router 컴포넌트는 window의 location 값에 따라 렌더링할 컴포넌트를 선택해준다.
- Link 컴포넌트를 사용하면 내비게이션을 지원할 수 있다.
11.2.1 경로 내포시키기
- 사용자가 페이지 이동을 하더라도 UI중 일부가 계속 같은 위치에 남아있기를 원하는 경우가 있다.
- 과거의 경우 페이지 템플릿이나 마스터 페이지와 같은 패법을 통해 UI를 재활용해 왔다.
- 회사소개 페이지 밑에는 다른 콘텐츠를 표시할 하위 페이지를 만들자
- 구조
- 홈페이지 - http://localhots:3000/
- 404 오류 페이지 - http://localhots:3000/hot-potato
- 구조
- 컴포넌트 생성
- export function Services() { return ( <section> <h2>서비스</h2> <p> 서비스 소개~~ </p> </section> ) } export function History() { return ( <section> <h2>연혁</h2> <p> 연혁 소개~~ </p> </section> ) } export function Location() { return ( <section> <h2>위치</h2> <p> 위치 소개~~ </p> </section> ) }
- Router에 추가
- import React from "react"; import { Routes, Route } from "react-router-dom"; import { Home, About, Events, Products, Contact, Services, History, Location, Whoops404 } from "./pages" function App() { return ( <div> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} > <Route path="services" element={<Services />}></Route> <Route path="history" element={<History />}></Route> <Route path="location" element={<Location />}></Route> </Route> <Route path="/events" element={<Events />} /> <Route path="/products" element={<Products />} /> <Route path="/contact" element={<Contact />} /> <Route path="*" element={<Whoops404 />} /> </Routes> </div> ) } export default App
- About 컴포넌트의 하위 컴포넌트를 보여주려면 Outlet 컴포넌트를 사용해야 한다.
- import React from "react"; import { Link, useLocation, Outlet } from "react-router-dom"; export function About() { return ( <div> <h1>[회사소개]</h1> <Outlet /> </div> ) }
11.3 리디렉션 사용하기
- 한 경로를 다른 경로로 리디렉션을 해야할 수도 있다.
<aside> ❓ Redirect을 찾을 수가 없어서 오류가 발생import React from "react"; import { Routes, Route, Redirect } from "react-router-dom"; import { Home } from "./pages" function App() { return ( <div> <Routes> <Route path="/" element={<Home />} /> <Redirect from="services" to="about/services" /> </Routes> </div> ) } export default App
- </aside>
- 프로덕션에서 경로를 바꾸는 경우 사용자가 예전 경로로 접근할 수 있기 때문에 Redirect 컴포넌트를 사용하여 변경된 페이지로 이동 시킬 수 있다.
- useRoutes라는 훅을 사용해 애플리케이션의 라우팅을 설정 할 수 있다.<aside> ❓ Redirect은 동작 하지 않는데???
- </aside>
- import { useRoutes } from "react-router-dom"; import { About, Contact, Events, History, Home, Location, Products, Services, Whoops404 } from "./pages" function App() { let element = useRoutes([ { path: "/", element: <Home /> }, { path: "about", element: <About />, Children: [ { path: "services", element: <Services /> }, { path: "history", element: <History /> }, { path: "location", element: <Location /> } ] }, { path: "events", element: <Events /> }, { path: "products", element: <Products /> }, { path: "contact", element: <Contact /> }, { path: "*", element: <Whoops404 /> }, { path: "services", redirectTo: "about/services" }, ]) return element; } export default App
11.3.1 라우팅 파라미터
- 리액트 라우터의 다른 유용한 특징으로는 라우팅 파라미터를 설정할 수 있는 기능이 있다.
- 라우팅 파라미터는 URL에서 값을 얻을 수 있는 변수다.
- 콘텐츠를 걸러내거나 사용자 선호에 따라 여러 표시 방법을 제공해야 하는 데이터 주도 웹에서 라우팅 파라미터가 유용하다.
- 리랙트 라우터를 통해 한번에 한 색을 선택해 표시할 수 있는 기능을 추가해서 색 관리 앱을 개선하자.
- import React from "react"; import { render } from "react-dom"; import App from "./App"; import { BrowserRouter as Router } from "react-router-dom"; render( <Router> <App /> </Router>, document.getElementById("root") )
- ColorList와 ColorDetails라는 2가지 경로가 있다.
- import React from "react"; import { Routes, Route } from "react-router-dom"; import { ColorList, ColorDetails, AddColorForm } from "./ColorDetails"; function App() { return ( <div> <AddColorForm /> <Routes> <Route path="/" element={<ColorList />} /> <Route path=":id" element={<ColorDetails />} /> </Routes> </div> ) } export default App
- ColorsDetails.js 파일 안에 ColorDetails 라는 컴포넌트를 만들자.
- import React from "react"; export function ColorDetails() { return ( <div> <h1>Detils</h1> </div> ) } export function ColorList() { return ( <div> <h1>ColorList</h1> </div> ) } export function ColorProvider() { return ( <div> <h1>ColorProvider</h1> </div> ) } export function AddColorForm() { return ( <div> <h1>AddColorForm</h1> </div> ) }
- useParams 훅을 사용해 URL에 있는 값을 확인 할 수 있다.
- import React from "react"; import { useParams } from "react-router-dom"; export function ColorDetails() { let params = useParams(); console.log(params) return ( <div> <h1>Detils</h1> <h2>{params.id}</h2> </div> ) }
- useParams를 구조분해 하여 id를 가지고 colors 배열에서 올바른 색을 찾는다.
- import React from "react"; import { useParams } from "react-router-dom"; import { useColors } from "./" export function ColorDetails() { let { id } = useParams(); let { colors } = useColors(); let foundColor = colors.find(color => color.id === id); return ( <div> <h1>Detils</h1> <div style={{ backgroundColor: foundColor.color, height: 100, width: 100 }} > </div> <h1>{foundColor.title}</h1> <h1>{foundColor.color}</h1> </div> ) }
- ColorDetails 페이지로 내비케이션하는 방법으로는 useNavigate라는 리액트 훅을 사용하여 이동할 수 있다.
- useNavigate를 호출하면 다른 페이지로 내비게이션할 때 사용할 수 있다.
import React from "react"; import { useParams } from "react-router-dom"; import { useColors } from "./"; import { useNavigate } from "react-router-dom"; export function ColorList() { let navigate = useNavigate(); return ( <div> <h1>ColorList</h1> <section className="color" onClick={() => navigator(`/${id}`)} > Color 컴포넌트 </section> </div> ) }
728x90