React의 SPA(Single Page Application) 특성상
페이지를 하나의 페이지에 전부 담고 필요할 때 동적으로 화면을 바꿔가며 보여준다
React-Router-Dom은 이런 페이지 전환을 빠르고 부드럽게 하기 위해 사용한다
React-Router-Dom
그냥 a태그 쓰지 왜 이런 거 쓰냐고 할 수 있지만
a태그를 쓰면 전환될 때 깜빡이며 전환이 된다
이렇게 깜빡이는 현상을 개선하고자 routing을 한다
Router의 종류
Hash Router
url에 해쉬(#) 값을 이용하는 라우터
- 주소에 # 이 붙는다
- 검색엔진이 읽지를 못한다
- 별도의 서버 설정을 하지 않더라도 새로고침 시 오류가 발생하지 않는다. 이는 해시 라우터가 해쉬(#) 뒤의 값은 브라우저에서만 관리하고(라우팅 하는 사실을 서버가 모름) 서버는 기본 url로 서버에 데이터를 요청하기 때문이다.
- history API를 사용하지 않기 때문에 동적 페이지에 불리하다
Browser Router
- history api를 사용한다
- 별도의 서버 설정이 없다면 새로고침시 404 요류가 발생한다
- 큰 프로젝트에 적합하다
서버가 존재하고, 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')
}
여기에는 속성을 추가할 수 있는데
- place
- 기본값은 false이고, true로 설정한다면 이동후 뒤로 가기가 불가능한다
- 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
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;
useSearchParams
const [serchParams, setSearchParams] = useSearchParams();
값을 읽어오는 메서드
searchParams.get(key) 특정한 key의 value를 가져오는 메서드, 해당 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;
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 |