자바스크립트/러닝 리엑트

리액트 라우터

막이86 2023. 11. 13. 13:06
728x90

러닝 리엑트을 요약한 내용입니다.

  • 페이지 기반 웹사이트의 경우 이전 페이지나, 다음 페이지, 브라우저 주소 등을 사용해서 페이지 이동이 가능하다
  • 단일 페이지 웹사이트에서는 페이지 이동 기능이 문제가 된다.
    • 한 페이지 안에서 모든 일이 벌어지기 때문에
    • 브라우저 방문 기록, 채깔피, 이전페이지, 다음 페이지 등의 기능은 라우팅 솔루션을 사용해야 한다.
  • 라우팅은 클라이언트의 요청을 처리할 종말점을 찾는 과정이다.
  • 앵귤러, 엠버, 백폰과 달리 리액트는 표준 라우터가 없다.
    • 마이클 잭슨, 라이언 플로렌스는 리액트 라우터라는 이름의 라우터를 만들었다.
    • 우버, 젠데스크, 페이팔, 비메오 등의 회사가 리액트 라우터를 채택했다.

1.1.1 라우터 사용하기

  • 리액트 라우터의 기능을 보여주기 위해 회사 소개, 이벤트, 제품, 고객 지원 메뉴가 있는 전형적인 웹사이트를 SPA 방식으로 만들자.
  • [그림 11-1]
  • 웹사이트의 사이트맵은 홈페이지, 각 메뉴 항목에 해당하는 섹션을 위한 페이지, 404 Not Found 오류를 처리하기 위한 오류 페이지 [그림 11-2] 페이지 제목과 경로
  • 라우터를 사용하면 이 웹사이트 각 섹션에 대한 경로를 설정할 수 있다.
    • 각 경로는 브라우저의 주소창에 넣을 수 있는 종말점을 뜻한다.
    • 요청 받은 경로에 따라 적적한 콘텐츠를 렌더링해 보여준다.
  • 리액트 라우터와 리액트 라우터 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 파일 수정
    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
    
  • 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를 재활용해 왔다.
  • 회사소개 페이지 밑에는 다른 콘텐츠를 표시할 하위 페이지를 만들자
  • 컴포넌트 생성
  • 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 리디렉션 사용하기

  • 한 경로를 다른 경로로 리디렉션을 해야할 수도 있다.
    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을 찾을 수가 없어서 오류가 발생
  • </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

'자바스크립트 > 러닝 리엑트' 카테고리의 다른 글

리액트와 서버  (1) 2023.11.13
리액트 테스트  (1) 2023.11.13
Suspense  (0) 2023.11.13
데이터 포함시키기  (0) 2023.11.13
훅스 컴포넌트 개선하기  (1) 2023.11.13