Javascript/React

[React]React-Router-Dom

LSH2118 2024. 9. 28. 17:31

 React의 SPA(Single Page Application) 특성상 

페이지를 하나의 페이지에 전부 담고 필요할 때 동적으로 화면을 바꿔가며 보여준다

 

React-Router-Dom은 이런 페이지 전환을 빠르고 부드럽게 하기 위해 사용한다


React-Router-Dom

출처: 생활코딩

그냥 a태그 쓰지 왜 이런 거 쓰냐고 할 수 있지만

a태그를 쓰면 전환될 때 깜빡이며 전환이 된다

 

이렇게 깜빡이는 현상을 개선하고자 routing을 한다

 

Router의 종류

Hash Router

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

  1. 주소에 # 이 붙는다
  2. 검색엔진이 읽지를 못한다
  3. 별도의 서버 설정을 하지 않더라도 새로고침 시 오류가 발생하지 않는다. 이는 해시 라우터가 해쉬(#) 뒤의 값은 브라우저에서만 관리하고(라우팅 하는 사실을 서버가 모름) 서버는 기본 url로 서버에 데이터를 요청하기 때문이다.
  4. history API를 사용하지 않기 때문에 동적 페이지에 불리하다

Browser Router

  1. history api를 사용한다
  2. 별도의 서버 설정이 없다면 새로고침시 404 요류가 발생한다
  3. 큰 프로젝트에 적합하다
서버가 존재하고, SEO가 필요한 프로젝트라면 BrowserRouter를 사용하는 것이 좋고, 그 외에 개인적이거나 작은 단위의 프로젝트라면 HashRouter를 사용해도 괜찮다

 

React-Router-Dom

React로 생성된 SPA(Single Page Application) 내부에서 부드럽게 페이지 이동이 가능하게 해주는 라이브러리

>     npm i react-router-dom

 

사용하기

import { BrowserRouter, Link,  useNavigate} from 'react-router-dom'

 

Browser Router

  • history api를 통해 history객체를 생성한다
    • history api란? 우리가 페이지를 이동할 때 경로를 stack형태로 저장하고 뒤로 가기 할 때 그걸 빼면서 작동이 된다
  • 라우팅을 진행할 컴포넌트 상위에  컴포넌트를 생성하고 <BrowserRouter> 감싸주어야 한다
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import MyComponent from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter> // <- 이렇게
      <div>
        <h1>BrowserRouter</h1>
      </div>
      <MyComponent />
    </BrowserRouter>
  </React.StrictMode>
);

 

Link

Link 컴포넌트는 라우터 내에서 직접적으로 페이지 이동을 하고자 할 때 사용되는 컴포넌트이다

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

function LinkExample(){
  return (
    <div>
      <Link to='https://github.com/LeeSangHyeok0731'> github </Link>
      <Link to='youtube.com'> youtube </Link>
    </div>
  );
}

export default LinkExample;

이렇게 <Link> 안에 to='url'을 넣어서 작동한다

 

1. Relative

계층 구조에 상대적이다.
상대 경로 표현이 가능하므로, ./.. 과 같은 표현도 사용이 가능하다.

 

2. preventScrollReset

페이지 중간에 있는 콘텐츠 내부에서 tab 목록을 누르는 것과 같은 시도를 할 때, 기존의 Link 컴포넌트였다면 클릭 시 스크롤이 초기화되어 페이지 가장 위로 이동하게 된다.
그러나 이 속성을 true로 설정해 주면 이를 방지할 수 있다

 

3. state

useLocation 훅과 연계하여 특정 state를 넘겨주는 것도 가능하다.

<Link to="new-path" state={{ some: "value" }} />

let { state } = useLocation();

 

useNavigate

이 훅을 사용하면 특정 이벤트가 발생했을 때 이동할 수 있다

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

const navigate = useNavigate();

const onClick = () => {
	navigate('url')
}

 

여기에는 속성을 추가할 수 있는데

  1. place
    • 기본값은 false이고, true로 설정한다면 이동후 뒤로 가기가 불가능한다
  2. state
    • state전달 기능이 있다
navigate("url", { state: { cardId: cardId } });

const location = useLocation();
const { cardId } = location.state;

 

중첩라우팅

특정 페이지 내에서 하위 페이지를 만들 수 있고, 해당 페이지마다 경로를 이용한 데이터 전달이 가능하다

한 중첩 라우팅을 구현할 경우 해당 하위 페이지 이외에는 콘텐츠가 바뀌지 않는다는 특징이 있다

<Route path="/parents" element={<Parents />}>
    <Route path="/child" elememt={<Child />} />
</Route>

이렇게 위에 /parents주소 안에 /child를 생성하면 자동으로 /child/parents의 하위 라우팅이 되었다고 판단한다

 

이렇게 해두면 우리가 /parents/child로 이동하면 /parents/child가 동시에 렌더링이 된다
하지만 단지 이렇게만 한다고 중첩라우팅이 되지는 않는다


실제로 라우팅이 발생하는 부모요소인 /parents에서 하위페이지가 렌더링 될 자리를 명시해줘야만 한다
그래서 우리가 사용해야 될게 바로 outlet 컴포넌트이다

 

Outlet

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

function Parents() {
  return (
    <div>
      <div>
        <h1>중첩라우팅</h1>
        <h1>Outlet의 예시</h1>
      </div>
      <Outlet />
    </div>
  );
}

이렇게 Parents컴포넌트에 Outlet컴포넌트를 넣어 줌으로써 하위요소인 Child컴포넌트를 렌더링 할 수 있다

(주소가 일치하는 경우)

 

Params

주소 경로 내부에 특정 데이터를 넣어 전달하는 것

즉 특정 url경로의 값을 가져와서 활용할 수 있다

 

크게 url 파라미터퀴리스트링으로 나누어진다

 

url 파라미터

주소="https://faker/lol/1234"

<Route path="lol/:id" element={<Lol />} />

이렇게 경로를 /lol/:id에서 : 표현해 준 id는 Lol컴포넌트에 파라미터로 전달이 되어 Lol컴포넌트 내에서 useParams훅을 통해 추출하고 사용할 수 있다.

 

쿼리스트링

?, & 을 기준으로 key와 value로 나눠 데이터를 전달받는다
그 후 전달받은 값은 useLocation훅을 통해 추출하고 사용할 수 있다

 

예전까지는?, &를 직접 분리해서 추출을 해야 했는데 , useSearchParams를 통해서 그러한 불편함을 해소했다

 

특징

  • url파라미터
    • ID, 이름등 특정 데이터를 조회할 때 사용
    • 일반적인 변수, 상수값들을 전달하기 위해 사용
  • 퀴리스트링
    • 키워드 검색, 페이지네이션, 정렬방식 등 데이터 조회에 필요한 옵션을 전달할 때 사용
    • key, value 형태의 데이터이므로 json이나 객체 형태의 데이터를 전달하기 용이하다
 

useParams

url파라미터를 조회할 때 사용한다
import React from 'react';
import { useParams } from 'react-router-dom';

function Lol(){
  let { id } = useParams();

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

export default Lol;
이렇게 해 놓으면 /lol/:id인 id로 1234가 불러와 진다
만약 https://faker/lol/1234/1212 이고 /lol/:id/:name라고 해 놓으면 1234id1212name에 불러올 수 있다

 

useSearchParams

쿼리스트링을 추출하는데 사용된다
const [serchParams, setSearchParams] = useSearchParams();​
searchParams는 유용한 메소드를 많이 포함하고 있다

setSearchParams는  함수의 인자에 객체와 문자열을 넣어주면 현재 url의 쿼리스트링을 변경할 수 있다

자주 사용하는 메소드는

값을 읽어오는 메서드

searchParams.get(key) 특정한 key의 value를 가져오는 메서드, 해당 keyvalue가 두 개 이상이라면 처음의 값을 반환한다

searchParams.getAll(key) 특정 key에 해당하는 모든 value를 가져오는 메서드


값을 변경하는 메서드

searchParams.set(key, value) 인자로 전달한 key값을 value로 설정한다. 만일 기존에 key에 대한 값이 존재했다면 덮어 씌운다
 
searchParams.append(key, value) 기존 값을 변경 혹은 삭제하지 않고 추가한다.
 
 

key와 value

useSearchParams를 설명할 때 key와 value의 설명이 빠진 것 같아서 추가로 설명하겠다

 

url에서 쿼리스트링은 ? 뒤에 나오는 부분으로, key=value를 한쌍으로 이루어져 있습니다

 

https://profil/?name=Lee&age=17&major=frontend

이라는 url이 있다고 가정해 보자

 

그럼 퀴리스트링은 ?name=lee&age=17&major=frontend부분으로 

key value
name lee
age 17
major frontend
 위 표처럼 표현되어서 
 
searchParams.get('name')

위 코드의 의미는 "name"이라는 key에 해당하는 값, 즉 "lee"를 반환합니다

 

searchParams.set('name', "jeon")

마찬 가지로 위 코드의 의미는 "name"이라는 key에 해당하는 값인 "lee"를 "jeon"으로 바꾼다

활용

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

function Example() {
  const [searchParams] = useSearchParams();
  const name = searchParams.get('name');
  const age = searchParams.get('age');

  return (
    <div>
      <p>Name: {name}</p>
      <p>Age: {age}</p>
    </div>
  );
}

export default Example;

 

만약 이런 코드에서 url이 http://example.com?name=Lee&age=17이라면 화면에는
Name: Lee
Age: 17
이 출력된다
import React from 'react';
import { useSearchParams } from 'react-router-dom';

function Example() {
  const [searchParams, setSearchParams] = useSearchParams();
  const name = searchParams.get('name');
  const age = searchParams.get('age');
  const updateQuery = () => {
    setSearchParams({ name: 'Lee', age: 'age + 1' });
  };

  useEffect(() => {

  }, [searchParams])

  return (
    <div>
      <p>Name: {name}</p>
      <p>Age: {age}</p>
      <button onClick={updateQuery}>age + 1</button>
    </div>
  );
}

export default Example;

이렇게 하면 아까와 마찬가지로

Name: Lee
Age: 17

이 출력이 되고

 

그 후 버튼을 누르면 나이가 하나 증가돼서 나온다


결론

아마 내가 현재 쓴 글 중에 가장 길고 열심히 적은 글이지 아닐까 싶다

하지만 그렇게 긴 만큼 중요하기에 꼭 공부해두는 게 좋을 것 같다

'Javascript > React' 카테고리의 다른 글

[React]React-Markdown  (0) 2024.12.10
[React]심심할땐 뻘짓이지  (0) 2024.11.19
[React]React-Helmet  (0) 2024.11.04
[React]Custom Hook  (0) 2024.10.14
[React] 리엑트가 뭐길래?  (0) 2024.08.07