가수면

Router 본문

React/라이브러리

Router

니비앙 2022. 12. 3. 23:28

패키지 설치

yarn add react-router-dom

 

폴더 구성

 

라우터 설정

Router.js

대문자로 넣었어도 주소는 소문자로도 먹힘

import React from "react";
// 1. react-router-dom을 사용하기 위해서 아래 API들을 import 합니다.
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "../Pages/Home";
import About from "../Pages/About";
import Contact from "../Pages/Contact";
import Works from "../Pages/Works";

// 2. Router 라는 함수를 만들고 아래와 같이 작성합니다.
//BrowserRouter를 Router로 감싸는 이유는, 
//SPA의 장점인 브라우저가 깜빡이지 않고 다른 페이지로 이동할 수 있게 만들어줍니다!
const Router = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="About" element={<About />} />
        <Route path="Contact" element={<Contact />} />
        <Route path="Works" element={<Works />} />
      </Routes>
    </BrowserRouter>
  );
};

export default Router;

App.js

import Router from './Shared/Router';

function App() {
  return <Router />;
}

export default App;

 

페이지 이동 훅

버튼

// src/pages/home.js
import { useNavigate } from "react-router-dom";

const Home = () => {
  const navigate = useNavigate();

  return (
    <button
      onClick={() => {
        navigate("/works");
      }}
    >
      works로 이동
    </button>
  );
};

export default Home;

링크

<Link to="/contact">    =>   절대 경로로 이동 (/주소)

<Link to="contact">     =>   상대 경로로 이동 (주소 뒤 +)

import { Link, useLocation } from "react-router-dom";

const Works = () => {
  const location = useLocation();
  console.log("location :>> ", location);
  return (
    <div>
      <div>{`현재 페이지 : ${location.pathname.slice(1)}`}</div>
      <Link to="/contact">contact 페이지로 이동하기</Link>
    </div>
  );
};

export default Works;

 

페이지 정보 확인 훅

// src/pages/works.js

import { useLocation } from "react-router-dom";

const Works = () => {
  const location = useLocation();
  console.log("location :>> ", location);
  return (
    <div>
      <button>버튼</button>
    </div>
  );
};

export default Works;

 

레이아웃 양식

Layout.js을 아래 같이 작성해준 뒤 Router.js의 태그들을 Layout 태그로 감싸주기

// src/shared/Layout.js

import React from 'react';

const HeaderStyles = {
  width: '100%',
  background: 'black',
  height: '50px',
  display: 'flex',
  alignItems: 'center',
  paddingLeft: '20px',
  color: 'white',
  fontWeight: '600',
};
const FooterStyles = {
  width: '100%',
  height: '50px',
  display: 'flex',
  background: 'black',
  color: 'white',
  alignItems: 'center',
  justifyContent: 'center',
  fontSize: '12px',
};

const layoutStyles = {
  display: 'flex',
  flexDirection: 'column',
  justifyContent: 'center',
  alignItems: 'center',
  minHeight: '90vh',
}

function Header() {
  return (
    <div style={{ ...HeaderStyles }}>
      <span>Sparta Coding Club - Let's learn React</span>
    </div>
  );
}

function Footer() {
  return (
    <div style={{ ...FooterStyles }}>
      <span>copyright @SCC</span>
    </div>
  );
}


function Layout({ children }) {
  return (
    <div>
      <Header />
      <div style={{ ...layoutStyles }}>
        {children}
      </div>
      <Footer />
    </div>
  );
}

export default Layout;

 

Dynamic Route

 

Router.js

<Route path="works" element={<Works />} />
<Route path="works/:id" element={<Works />} />

 

useParams 훅

path에 있는 아이디값을 조회할 수 있게 해주는 훅

상세 페이지(works.jsx -> work.jsx) 형태

// src/pages/Work.js

import React from "react";
import { useParams } from "react-router-dom";

const data = [
  { id: 1, todo: "리액트 배우기" },
  { id: 2, todo: "노드 배우기" },
  { id: 3, todo: "자바스크립트 배우기" },
  { id: 4, todo: "파이어 베이스 배우기" },
  { id: 5, todo: "넥스트 배우기" },
  { id: 6, todo: "HTTP 프로토콜 배우기" },
];

function Work() {
  const param = useParams();

  const work = data.find((work) => work.id === parseInt(param.id));

  return <div>{work.todo}</div>;
}

export default Work;

 

 


v6 바뀐 형식

index파일

APP -> Root

Outlet가 children같은 역할을 해줌 (Root뿐만이 아니라 children이 상대 경로로 붙는 페이지마다 넣어주면 됨)

user.tsx에 자식이 있다면 Outlet이 사용됨

import React from "react";
import { Link, Outlet } from "react-router-dom";

const User = () => {
  return (
    <div>
      <h1>유저</h1>
      <Link to="followers">팔로워</Link>
      <Outlet />   //Outlet 위치에 따라 Followers컴포넌트 내용 렌더링 위치가 달라짐
    </div>
  );
};

export default User;

 

Router

 

에러 핸들링

 

useOutletContext

자식 페이지들에 데이터 보내기

import React from "react";
import { Link, Outlet, useParams } from "react-router-dom";
import { users } from "../../components/db";

const User = () => {
  const { userId } = useParams();
  return (
    <div>
      <h1>
        User with id {userId} is named: {users[Number(userId) - 1].name}
      </h1>
      <Link to="followers">팔로워</Link>
      <Outlet
        context={{
          nameOfUser: users[Number(userId) - 1].name,
        }}
      />
    </div>
  );
};

export default User;

데이터 받기

import React from "react";
import { useOutletContext } from "react-router-dom";

interface IFollowersContext {
  nameOfMyUser: string;
}

const Followers = () => {
  const { nameOfMyUser } = useOutletContext<IFollowersContext>();
  return <div>여기는 {nameOfMyUser}의 팔로워</div>;
};

export default Followers;

예시 1)

헤더에서 가져온 데이터를 useOutletContext를 통해 Root에서  뿌려주면 모든 페이지에 데이터를 내려줄 수 있음 

 

예시 2)

함수 내려주기

const Root = () => {
  const [isDark, setIsDark] = useState(false);
  const toggleDark = () => setIsDark((isDark) => !isDark);
  return (
    <div>
      <ThemeProvider theme={isDark ? darkTheme : lightTheme}>
        <GlobalStyle />
        <Outlet context={{toggleDark}} />
      </ThemeProvider>
    </div>
  );
};

함수 내려받기

interface ICoinsProps {
  toggleDark: () => void;
}

const Coins = () => {
  const { toggleDark } = useOutletContext<ICoinsProps>();
.
.
.
<button onClick={toggleDark}>토글 모드</button>

 

Link를 이용해 데이터 내려주기

데이터 보내기 (state 활용)

          <CoinsList>
            {coins.map((coin) => (
              <Coin key={coin.id}>
                <Link to={`/${coin.id}`} state={coin.name}>
                  <Img src={`https://cryptocurrencyliveprices.com/img/${coin.id}.png`} />
                  {coin.name} &rarr;
                </Link>
              </Coin>
            ))}
          </CoinsList>

데이터 받기

useLocation()사용

 

useSearchParams

  const [readSearchParams, setSearchParams] = useSearchParams();
  console.log(readSearchParams);  //URLSearchParams {}

URLSearchParams(자바스크립트 내장 메소드)를 이용해 많은 것들을 할 수 있음. 자세한 내용은 아래 참조

https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams

 

URLSearchParams - Web APIs | MDN

The URLSearchParams interface defines utility methods to work with the query string of a URL.

developer.mozilla.org

 

예시)

readSearchParams.has("users")   =>  window.location.pathname === "users" 와 같은 기능

setSearchParams()에 setTimeout을 섞어 url을 조작할 수도 있음

현재 URL의 query string을 읽고 수정하는데 유용함.

  const keyword = new URLSearchParams(location.search).get("keyword");
  console.log(keyword);

 

 

useMatch()

유저가 해당 페이지에 있는지 없는지 확인할 수 있음

  const priceMatch = useMatch("/:coinID/price");
  console.log(priceMatch);

 

'React > 라이브러리' 카테고리의 다른 글

[Styled Components] Styled Components Global Style  (0) 2022.12.17
[Redux] Redux ToolKit thunk  (0) 2022.12.10
[Redux] Redux ToolKit  (0) 2022.12.09
[Styled Components] Styled Components  (0) 2022.12.02
[Redux] Redux  (0) 2022.12.02
Comments