반응형
Notice
Recent Posts
Recent Comments
Link
관리 메뉴

짧은코딩

페이지 라우팅 본문

인프런, 유데미/한입 크기로 잘라 먹는 리액트

페이지 라우팅

5_hyun 2022. 6. 16. 16:07
반응형

PAGE ROUTING

ROUTER: 데이터의 경로를 실시간으로 지정해주는 역할

ROUTING: 경로를 정해주는 행위와 과정을 다 포함하는 말, 어떤 네트워크 내에서 통신 데이터를 보낼 경로를 선택하는 과정

PAGE ROUTING: 요청에 따라서 어떤 페이지를 돌려줄지 정해주는 것

 

-MPA(Multipage Application)

이렇게 여러 개의 페이지를 준비했다가 요청이 들어오면 적절한 페이지를 돌려주는 것을  MPA라고 한다.

 

-SAP(Single Page Application)

리액트는 MPA가 아닌 SPA를 사용한다.

SPA는 페이지가 하나 밖에 없는 간단한 어플리케이션이다.

SPA는 페이지를 이동할 때 위 부분이 전혀 깜빡이지가 않는다. 핸드폰에서 사용하는 것 처럼 이동이 빠르다.

 

우선 처음엔 이렇게 서버를 통해서 index.html을 가져온다.

 

그리고 다른 페이지로 이동하고 싶어서 클릭을 하면

리엑트는 페이지가 1개라서 더 이상 서버에서 가져올 수 없다. 대신 서버가 아니고 리액트 앱이 알아서 페이지를 업데이트 한다. 브라우저가 알아서 처리하면 되니까 서버랑 통신하는 시간 없이 빠르게 전환할 수 있다. 그 외의 필요한 데이터들만 서버를 통해 가져온다.

=> 이렇게 렌더링 하는 방식을 클라이언트 쪽이 렌더링 한다고해서 Client Side Rendering, 즉 CSR이라고 부른다.

     따라서 리액트는 SPA 방식을 사용하면서 CSR로 렌더링을 한다.

 

적용하기

emotion-diary라는 폴더를 만들고 npx create-react-app 명령어를 통해 새로 만들어줬다.

 

page routing을 하기 위해서 아래 사이트에 들어가서 라이브러리를 이용해야 한다.

https://reactrouter.com/

 

Declarative routing for React apps at any scale | React Router

Version 6 of React Router is here! React Router v6 takes the best features from v3, v5, and its sister project, Reach Router, in our smallest and most powerful package yet.

reactrouter.com

 

사이트에서 이 명령어를 이용해 설치를 해준다.

 

설치를 하고 나서

이런식으로 pages와 그 안에 사용할 페이지를 만들어준다. 그리고 안에 기본적인 내용을 입력해준다. 

이렇게 4개를 만들고 특정 주소지에 4개를 연결해 페이지 라우팅을 시도한다.

 

-App.js

import "./App.css";
import { BrowserRouter } from "react-router-dom";

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <h2>App.js</h2>
      </div>
    </BrowserRouter>
  );
}

export default App;

이렇게 BrowserRouter로 감싸주면 이 감싸준 부분은 URL과 맵핑될 수 있다.

 

 

import "./App.css";
import { BrowserRouter, Route, Routes } from "react-router-dom";

import Home from "./pages/Home";
import New from "./pages/New";
import Edit from "./pages/Edit";
import Diary from "./pages/Diary";

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <h2>App.js</h2>
        <Routes>
          <Route path="/" element={<Home />} />
        </Routes>
      </div>
    </BrowserRouter>
  );
}

export default App;

그리고 브라우저의 URL이 바뀌게되면 어떤 컴포넌트가 렌더링해서 그 컴포넌트가 페이지 역할을 할 것인지 결정하기 위해서 바뀔 부분을 Routes 컴포넌트로 감싸준다. Route 컴포넌트는 실질적으로 URL 경로와 컴포넌트를 맵핑 시켜주는 컴포넌트이다.

이런 화면이 나오게 된다.

 

따라서 path="/"는 index 컴포넌트를 가리키고 있으면 Home 컴포넌트를 맵핑하라는 의미이다.

만약 index 컴포넌트를 가리킨게 아니고 pages를 가리키게 하면 Home 컴포넌트는 나오지 않는다.

그리고 개발자 도구에 들어가면 pages와 일치하는 라우터가 없다고 뜬다.

 

-나머지 New, Edit, Diary도 구현

import "./App.css";
import { BrowserRouter, Route, Routes } from "react-router-dom";

import Home from "./pages/Home";
import New from "./pages/New";
import Edit from "./pages/Edit";
import Diary from "./pages/Diary";

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <h2>App.js</h2>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/new" element={<New />} />
          <Route path="/edit" element={<Edit />} />
          <Route path="/diary" element={<Diary />} />
        </Routes>
      </div>
    </BrowserRouter>
  );
}

export default App;

이렇게 라우트 컴포넌트에 추가하면

이렇게 나오게된다. 

App.js는 계속 나오는 이유가 Routes 컴포넌트 안에만 업데이트 되도록 했기 때문이다.

 

-페이지로 이동하는 요소 만들기

HTML에서는 a 태그를 이용해서 만들었다. 하지만 a 태그로 만들면 새로고침을 하게된다. 이것은 SAP가 아닌 MPA이다.

a 태그는 페이지 외부로 나가는 URL에서만 사용한다.

 

Components 폴더를 만들고 그 안에 RouteTest.js를 만든다.

SPA를 사용하기 위해서는 Link를 사용하고 to에 어느 컴포넌트를 사용할 것인지 알려준다.

 

App.js

import "./App.css";
import { BrowserRouter, Route, Routes } from "react-router-dom";

import RouteTest from "./Components/RouteTest";

import Home from "./pages/Home";
import New from "./pages/New";
import Edit from "./pages/Edit";
import Diary from "./pages/Diary";

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <h2>App.js</h2>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/new" element={<New />} />
          <Route path="/edit" element={<Edit />} />
          <Route path="/diary" element={<Diary />} />
        </Routes>
        <RouteTest />
      </div>
    </BrowserRouter>
  );
}

export default App;

그리고 App.js에 가서 import하고 <RouteTest/>를 추가하면 페이지 이동 요소가 만들어진다.

 

이렇게 하여 굉장히 빠르게 이동할 수 있다.

 

React Router 응용

1. Path Variable(useParams)

일기를 저장하다 보면 diary/1, diary/2 이런식으로 저장해야한다. 이 블로그 글만 해도 이런식으로 저장한다.

          <Route path="/diary/:id" element={<Diary />} />

이런식으로 사용할 수 있다. 그러면 URL 뒤에 /diary/1을 하면 diary가 나오게된다. 하지만 diary만 하면 나오지 않게되는 것이 문제점이다.

 

이럴땐 그냥

          <Route path="/diary" element={<Diary />} />

이렇게 추가하면 되는데 이 프로젝트에선 id가 없는 일기는 만들지 않을 것이라서 사용하지 않는다.

 

-Diary.js

import { useParams } from "react-router-dom";
//리액트 hooks는 아니지만 별도 라이브러리가 제공하는 hooks를
// 사용자 정의 hooks를 커스텀 hooks라고 부른다.

const Diary = () => {
  const { id } = useParams();

  return (
    <div>
      <h1>Diary</h1>
      <p>이곳은 일기 상세 페이지 입니다.</p>
    </div>
  );
};

export default Diary;

useParams를 이용하면 전달 받아서 들어오는 Path Variable들을 모아서 객체로 갔다주는데, App.js에서 id로 부르기로 약속해서 id로 꺼내온다.

2. Query String(useSearchParams)

Query는 웹 페이지에 데이터를 전달하는 가장 간단한 방법이다.

Query String은 path variable과 굉장히 유사한 역할을 한다. 

 

/edit?id=10&mode=dark 이런식으로 name과 value를 엮어서 데이터를 전송할 수 있는 것을 Query String이라 한다. 다른 변수도 전송하고 싶으면 &를 사용한다.

 

코드 수정을 하지 않고 ?id=10&mode=dark를 붙여도 잘 작동한다.

이런걸 보면 별도의 처리를 안해줘도 자동으로 맵핑이 된다. 따라서 물음표 뒤에 경로는 페이지 라우팅에 영향을 주지 않는다.

 

-Edit.js

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

const Edit = () => {
  const [searchParams, setSearchParams] = useSearchParams();

  const id = searchParams.get("id");
  console.log("id: ", id);

  const mode = searchParams.get("mode");
  console.log("mode: ", mode);

  return (
    <div>
      <h1>Edit</h1>
      <p>이곳은 일기 수정페이지 입니다.</p>
      <button onClick={() => setSearchParams({ who: "salah" })}>
        QS 바꾸기
      </button>
    </div>
  );
};

export default Edit;

[] 비구조화 할당을 사용한다. useSearchParams 훅을 사용하면 된다. 이런식으로 id와 mode 둘 다 가져올 수 있다. 비구조화 할당을 한 부분은 이름을 자유롭게 사용 가능하지만 useSearchParams는 꼭 써줘야 한다.

 

searchParams는 get을 이용해 전달받은 쿼리 스트링을 꺼내 쓸 수 있다.

setSearchParams는 useState를 떠올릴 수 있게 생겼다. searParams를 변경 시킬 수 있다. 이 말은 즉 query string이 변경될 수 있다는 말이다.

 

setSearchParams를 통해 query string을 바꿨다.

3. Page Moving(useNavigate)

import { useSearchParams, useNavigate } from "react-router-dom";

const Edit = () => {
  //여기 추가
  const navigate = useNavigate(); 
  const [searchParams, setSearchParams] = useSearchParams();

  const id = searchParams.get("id");
  console.log("id: ", id);

  const mode = searchParams.get("mode");
  console.log("mode: ", mode);

  return (
    <div>
      <h1>Edit</h1>
      <p>이곳은 일기 수정페이지 입니다.</p>
      <button onClick={() => setSearchParams({ who: "salah" })}>
        QS 바꾸기
      </button>
      {/* 밑 버튼 추가 */}
      <button
        onClick={() => {
          navigate("/home");
        }}
      >
        Home으로 가기
      </button>
      {/* 밑 버튼 추가 */}
       <button
        onClick={() => {
          navigate(-1);
        }}
      >
        뒤로가기
      </button>
    </div>
  );
};

export default Edit;

useNavigate라는 hook은 페이지를 이동시킬 수 있는 함수를 반환해주는데 이를 navigate로 만들어서 호출하면 이렇게 Home으로 이동 가능하다. 이것은 로그인 하지 않은 사용자가 로그인 페이지로 가려할 때, 로그인이 되었는지 검사해서 로그인 페이지로 보내는 기능을 위해 존재한다.

=> useNavigate는 link 태그를 클릭 안했을 때도 페이지를 바꿀 수 있다.

 

그리고 뒤로 가기도 해줄 수 있다. navigate(-1)을 해주는 이유는 뒤로 한번가기 때문이다.

반응형
Comments