React-Router

Hyun Kyung Nam·2024년 3월 31일
0

개념정리

목록 보기
13/14
post-thumbnail

node js에서 사용하던 router와는 너무 다른 React router. 이 개념을 정리해야 프로젝트에서 페이지를 만들고 컴포넌트를 가져다 쓸 수 있을 것 같아서 문서도 읽고 검색도 해가며 열심히 정리하려고 한다. (document는 읽기 어렵게 되어있고 여러 블로그 전전해가면서 공부하고 정리해보았습니다)

React-Router

SPA, MPA란 ?

SPA(Single Page Application)

  • 단일페이지(idex.html)로 돌아가는 애플리케이션
  • 브라우저에서 자바스크립트를 이용해 단일 웹 페이지 상의 HTML요소를 동적으로 생성 및 조작
  • 페이지를 최초에 한 번만 로드하고 그 이후부터는 변화가 생기는 부분에서만 AJAX로 처리
  • 검색 엔진 최적화(SEO)에 적합하지 않음
  • mobile App에 많이 사용
  • React, Svelte, Vue.js와 같은 라이브러리로 개발 가능
  • Gmail, Google Maps, Facebook, Github등

MPA(Multi Page Application)

  • 여러개의 페이지로 구성된 애플리케이션
  • 브라우저에서 데이터를 보여주거나 데이터를 서버에게 전달할 때마다 화면이 전환 됨
  • 전자상거래 사이트 등 큰 애플리케이션은 MPA를 많이 사용
  • 누를때마다 로딩바가 돌아가는건 다 MPA라고 생각하면 된다!
  • 첫 로딩시에는 MPA가 빠르지만 그 이후는 SPA보다 느림

React Router 특징

CSR(client side routing)

  • React router는 client side routing을 가능하게 한다. 전통적인 웹사이트들은 브라우저가 웹서버에 document를 요청하고 CSS와 javascript를 download및 evaluate하고 서버로부터 받아온 HTML을 렌더링한다. 유저가 링크를 눌렀을 때 새 페이지에 대한 프로세스가 다시 시작된다.
  • Client side routing은 링크를 누를때마다 새 요청을 하지 않고 앱을 업데이트 하다. 즉, 새로운 UI를 렌더링하고 fetch를 통해 데이터 요청을 만들고 새로운 정보로 업데이트한다.
  • 브라우저가 다음페이지에 새 documnet 또는 css, js요청이 필요하지 않기 때문에 UX를 더 빠르게 만들 수 있다.

    CSR이 있다면 SSR(Server side rendering) 있겠죠? 이전 글에 CRA, SSR, CSR, SSR.. 정말 많은 용어들

Nested Routes

  • 중첩라우팅은 URL의 segment를 component hierarchy와 데이터에 연결 하는 것
  • Route안에 Route사용가능

Dynamic Segment

  • URL segment를 :를 이용하게 동적으로 사용 가능
  • 한 URL에 여러개의 dynamic segment 사용가능

Ranked Route Matching

  • URL을 route에 매칭할 때 React Router는 segment 수, static segment, dynamic segment, splat등 에 따라 rank를 매기고 가장 구체적으로 매칭되는 것을 선택
  • route 순서를 신경쓰지 않아도 됨
  • 물론 *을 사용할 때는 맨 마지막에 쓰기!
  • navigation section을 만들 때 해당 section이 선택되었을 때를 구분해 직접 표시를 해주었다면 React Router에서는 <NavLink>를 이용해 쉽게 구현 가능. isActive 또는 isPending을 사용해 쉽게 스타일을 적용할 수 있음
  • HTML<a href> 같이 <Link to> <NavLink to>는 중첩route를 이용해 상대 경로를 가질 수 있음

Data Loading

  • URL segments는 앱에 영구데이터로 매핑되기 때문에 React는 navigation중 데이터를 로딩하기 위해 conventional data loading hook을 제공. 중첩 route를 결합하면 특정한 URL의 여러 layout의 데이터가 병렬로 로드될수있음

Redirects

  • 데이터가 loading되거나 변할때 다른 route로 redirect 시킬수 있음

Pending Navigation UI

  • 페이지 렌더가 끝나기 전에 다음 페이지의 데이터가 로드 될때 pending Navigation UI를 이용하여 앱이 응답하지 않는 느낌을 주지 않도록 함

Data Mutations

HTML form은 link와 같은 navigation event가 발생하지만 React Router는 CSR HTML form을 지원, form 제출시 navigatioin event를 막고 body에 있는 FormData를 제출, 이 요청은 <Form action><Route action>에 매칭되는 곳에 보내짐, 폼 제출시 busy indicator, disable fildset등 표시 가능

Scroll Restoration

React Router는 스크롤 전에 data loading을 기다릴때의 browser scroll restoration을. emulate함, 이렇게하면 스크롤의 위치가 올바른 곳으로 복원됨

이외에도 여러개있지만.. 여기까지만 작성하고 특징이 비슷한것은 하나에 묶었다.

React Router Overview document
사실 이문서만 읽었을 때 이게 정말 무슨말이지.. 하는 생각이 많이 들었다. 다른 블로거들을 보면서 React Router설명을 보고 보니 이제 이해가 가는 친구들.. 뜬구름 잡는 이야기 같았는데 정리가 되고나니 오~~ 이러기능도 있어~~ 오~ 이런 것도 있어~ 하면서 문서를 재밌게 읽고 정리했다.정리하기 전까지 재미 없었다는 이야기 수업시간에 배운 내용은 정말 코딱지의 코딱지의 코딱지 만했다는 것을 깨닫고... 공부를 정말 많이해야겠다는 생각이 많이들었다.. ㅠ

React Router 사용법

  • React Router는 신규페이지를 불러오지 않는 상황에서 각각의 url에 따라 선택된 데이터를 하나의 페이지에서 렌더링 해주는 라이브러리
  • 사용자가 입력한 주소를 감지하는 역할을 하며, 여러 환경에서 동작할 수 있도록 여러 종류의 라우터 컴포넌트 제공
  • a태그를 이용할 때 생기는 무의미한 재 랜더링 예방=>> 속도가 빠르다!
  • react로 생성된 SPA 내부에서 페이지 이동이 가능하도록 만들어 주는 라이브러리 (실제 페이지 이동이 일어나는 것이 아니라 해당 페이지를 re-rendering 해서 보여주는것)
    설치
    - npm install react-router-dom
    - react-router-dom은 웹에서 사용, react-router-native은 앱에서사용, react-router는 웹과 앱 둘 모두 사용이라고 한다. 나는 web에서 사용할거니까 react-router-dom@6설치예정

    V6.4부터는 <BrowserRouter?, <MemoryRouter>, <HashRouter>, <NativeRouter>, <StaticRouter>를 지원하지 않는다. 대신 createBrowserRouter, createMemoryRouter, >createHashRouter, createStaticRouter지원.
    레거시 코드를 읽으려면 이전버전을 공부해야하고 새로운 버전도 공부해야한다는 말이죠?

BrowserRouter와 HashRouter

BrowserRouter

: HTML5를 지원하는 브라우저 주소 감지

  • history API 사용하여 UI업데이트(다시 로드하지않고 업데이트)
  • 동적 페이지에 적합
  • 새로고침 혹은 경로입력해서 갈 때 404에러 발생
    • 추가적인 세팅이 필요함(서버설정을 해주거나 basename설정해주기)
  • 큰 프로젝트에 적합

HashRouter

: url의 해쉬(#)값을 이용하는 라우터

  • 주소에 해쉬(#)가 붙는다
  • 정적인 페이지에 적합
  • 별도의 서버 설정을 하지 않더라도 새로고침시 오류가 발생하지 않는다. 이는 해쉬 라우터가 해쉬(#) 뒤의 값은 브라우저에서만 관리하고 서버는 라우팅하는 사실을 모르며 기본 url로 서버에 데이터 요청하기 때문이다.
  • history API를 사용하지 않기 때문에 동적 페이지에 불리
  • 블로그 정리한거보면 어떤건 검색엔진에 유리하다 불리하다를 반대로 적어 놓은게 많아서 공부가 또 필요하다는 생각이 들었다..^^ ㅎ

SEO(검색 엔진 최적화)

  • 웹사이트가 검색 결과에 더 잘보이도록 최적화 하는 과정(검색 순위 개선이라고도 함)
  •   

BrowserRouter

  • history API를 활용해 history 객체를 생성
  • history API는 내부적으로 stack자료구조의 형태를 띄기 때문에 사용자가 방문한 url 기록들을 차곡차곡 쌓는 형태로 저장
  • 라우팅을 진행할 컴포넌트 상위에 BrowserRouter 컴포넌트를 생성하고 감싸주어야함

Routes

  • 모든 route의 상위 경로에 존재해야하며, location 변경 시 하위에 있는 모든 route를 조회해 현재 location과 맞는 route를 찾아줌

Route

  • 현재 브라우저의 location(window.href.location 정보를 가져옴)의 상태에 따라 element를 렌더링
  • Route.element : path값과 url이 맞을 때 렌더링할 element <Element />형식으로 전달
  • Route.path : 현재 path이 url과 일치하는지 확인해 해당 url에 매칭된 element를 렌더링

Link

  • LINK 컴포넌트틑 라우터 내에서 직접적으로 페이지 이동을 하고자 사용할 때 사용 되는 컴포넌트
  • a 태그로 이루어져있지만 새로고침을 하지 않고 History API를 통해 브라우저의 주소의 경로만 바꾸는 기능이 내장 되어 있음
  • to속성에 경로를 넣어주는 방식으로 사용
    특징
  1. Relative
  • 계층 구조에 상대적
  • 상태 경로로 표현이 가능하므로, ./..와 같은 표현도 사용 가능
  1. preventScrollReset
  • 페이지 중간에 있는 컨텐츠 내부에서 tab목록을 누르는 것과 같은 시도를 할 때, 기존의 Link 컴포넌트였다면 클릭시 스크롤이 초기화 되어 가장 위로 이동하게 된다 ????이게 무슨말일까 ㅇㅂㅇ
  • 그러나 이 속성을 true로 하면 이를 방지 가능
  1. state
  • useLocation 훅과 연계하여 특정 state를 넘겨주는 것도 가능
  • Link의 special version
  • 특정 링크에 스타일을 넣어줄 수 있다.
  • activeStyle, activeClassName
  • 리액트 웹의 현재 URL와 to의 링크가 일치할 때 activeStyle과 activeClassName이 활성되 되고 일치하지 않으면 비활성화 된다.
  • 라우터 6으로 넘어가면서 NavLink에 스타일 줄려면 style 로 줘야됨, 특히 style 콜백으로 리턴하게 해서 isPending 이랑 isActive 파라미터가 생김
<NavLink
to="/messages"
className={({ isActive, isPending }) =>
isPending ? "pending" : isActive ? "active" : ""
}

useNavigate

  • 특정 이벤트(onChange, onClick 등)가 발생하였을 때 페이지 이동 트리거 가능
    속성
  1. replace
  • 기본값은 false 이고 true로 설정한다면 이동 후 뒤로가기 불가능
  1. state
  • link와 마찬가지로 state를 전달해 줄 수 있다.

중첩 라우팅

  • react-router-dom에서 가장 유용한 기능 중 하나
  • 특정 페이지 내에서 하위 페이지를 만들 수 있고 해당 페이지마다 경로를 이용한 데이터 전달도 가능
  • 중첩 라우팅을 구현할 경우 해당 하위 페이지 이외에는 컨텐츠가 변경되지 않음
<Route path="/about" element={<About />}>
  <Route path="location" element={<Location />}></Route>
</Route>

라우터 내부에 자식요소 Route를 만들어준다. /about 주소 하위에 /location이라는 주소가 하위 라우팅 되었다고 판단한다. /about/location으로 이동할 경우 Location 컴포넌트로 렌더링된다(물론 About 컴포넌트도 같이 렌더링 됨)

라우처에서 위와 같이 설정한 것만으로 아무변화가 생기지 않는다
실제로 해당 라우팅이 발생한 부모 요소인 About 페이지에 하위 라우팅 발생시 컴포넌트를 렌더링할 자리를 명시해주어야 하기 때문이고, 이 때 사용 되는 것이 Outlet 컴포넌트이다
Outlet

import { Outlet } from 'react-router-dom';

function About() {
  return (
    <div>
      <div>
        <h2>여기는 About 페이지입니다.</h2>
        <p>대충 쇼핑몰 페이지라는 뜻</p>
      </div>
      <Outlet />
    </div>
  );
}

About 컴포넌트 내부에 outlet컴포넌트를 렌더링해준다면 라우터에서 이를 인식하고 주소가 일치하는 경우 Outlet자리에 location 컴포넌트를 렌더링 함

Outlet없이 중첩 라우팅 구현하기

  • 라우터에 중첩라우팅 하고자 하는 주소에 다음과 같이 *을 추가해 중첩 라우팅이 발생할 주소임을 명시
<Routes>
  <Route path="/" element={<Home />}></Route>
  <Route path="/about/*" element={<About />}></Route>
  <Route path="/products" element={<Products />}></Route>
</Routes>

이 후 해당 About 컴포넌트에서 본래 Outlet이 들어갔던 자리에 마치 라우터를 구현 했던 것처럼 중첩 라우팅을 진행해주면 된다.

function About() {
  return (
    <div>
      <div>
        <h2>여기는 About 페이지입니다.</h2>
        <p>대충 쇼핑몰 페이지라는 뜻</p>
      </div>
      <Routes>
        <Route path="/location" element={<Location />}></Route>
      </Routes>
    </div>
  );
}

위와같이 작성하면 Outlet과 동일한 기능을 하는 중첩 라우팅 구현 가능

Params

  • 주소 경로 내부에 특정 데이터를 넣어 전달하는 것을 말하며 크게 url파라미터와 쿼리스트링으로 나누어짐

url파라미터

주소 : http://helloworld.com/hi/1
<Route path="/hi/:id" element={}>

여기서 :로 구분해준 id라는 값은 파라미터로 전달되어 Element 컴포넌트 내부에서 useParams훅을 통해 가져와 사용 가능, 1이 전달됨, 여러개 전달도 가능

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

const NewId = () => {
  let { id } = useParams();

  return (
    <div className="test">
      <p>현재 유저의 아이디는 { id } 입니다.</p>
    </div>
  )
}

export default NewId;

쿼리스트링

? &를 기준 으로 key, value형태로 데이터를 전달, 이렇게 전달 받은 후 useLocation 훅을 통해 추출하고 사용 가능
이전까지는 ? &를 직접 분리하고 값을 가져와 사용했어야했는데 useSearchParams를 사용하면 쉽게 사용 가능

useSearchParams

현재 위치에 대한 url의 쿼리스트링을 읽고 수정할 때 사용
useState와 사용법이 유사
serchParams는 URLSearchParams 객체이면서 쿼리스트링을 다루기 위한 다향한 메서드를 내장하고 있음
setSearchParams는 함수의 인자에 객체와 문자열을 넣어주면 현재 url의 쿼리스트링을 변경하는 기능을 제공

값을 읽어오는 메서드
searchParams.get(key) : 특정한 key의 value를 가져오는 메서드, 해당 key의 value가 두개 이상이하면 첫번째 값을 반환
searchParams.getAll(key) : 특정 key의 모든 value를 가져오는 메서드
값을 변경하는 메서드
setSearchParams.set(key, value) : 인자로 전달한 key값을 value로 설정한다. 기존의 key가 존재한다면 value를 덮어씌움
setSearchParams.append(key, value) : 기존 값을 변경 혹은 삭제하지 않고 축함

searchParams를 변경하는 메서드로 값을 변경하더라도 실제 url에는 이 정보가 반영되지 않는다. 만약 이를 변경하고자 한자면 setSearchParams에 searchParams를 인자로 전달해줘야한다. ???????????

const [serchParams, setSearchParams] = useSearchParams();
URL 파라미터쿼리스트링
ID, 이름, 특정 데이터를 조회할 때 사용키워드 검색, 페이지네이션, 정렬방식 등 데이터 조회에 필요한 옵션을 전달할 때 사용
일반적인 변수, 상수 값들을 전달하기 용이key, value 형태의 데이터 이므로 json이나 객체 형태의 데이터를 전달하기에 용이

참고 : Nohv, 갓대희

0개의 댓글