🐕 React Router는...
SPA는 하나의 페이지를 가지고 있지만 사실 한 종류의 화면만 사용하지는 않아요
전 라우터라고 해서 네트워크 공부할 때 나오는 라우터만 생각했는데
그냥 다른 주소에 따라 다른 뷰를 보여주는 과정을
"경로에 따라 변경한다"라는 의미로 라우팅이라고 한다 하네요..
리액트에서는 라우팅을 위해(주소에 따라 다른 화면을 보여주기 위해)
React Router라는 라이브러리를 많이 사용합니다.
👻React Router의 주요 컴포넌트
<BrowserRouter> |
<Routes> |
<Route> |
<Link> |
React Rounter의 주요컴포넌트는 크게 세가지로 나눌 수 있어용
종류는 저 네가지인데 용도로 나눠서 보면 이렇습니다.
router | route matchers | route changers |
<BrowserRouter> | <Routes> | <Link> |
<Route> |
라우터 역할을 해줄 BrowserRouter
얘는 웹 애플리케이션에서 HTML5의 History API를 사용해
페이지를 새로고침하지 않고도 주소를 변경할 수 있게 해줍니다.
또한 BrowserRouter가 상위에 작성되어있어야 React Router의 컴포넌트들을 사용할 수 있어요
경로를 매칭시켜줄 Routes와 Route
Routes 컴포넌트는 여러 <Route> 컴포넌트를 감싸서 그 중 경로가 일치하는
단 하나의 라우터만 렌더링을 시켜주는 역할을 해요!
Route 컴포넌트는 path 속성을 지정하여 해당 path에서 어떤 컴포넌트를 보여줄지 결정해줍니다.
Link 컴포넌트가 지정해주는 URL 경로와 일치해야만 작동해요!
<Routes>
<Route path="/" element={<Home />} />
{/* 경로는 path로 컴포넌트는 element로 연결해 줍니다. */}
<Route path="/mypage" element={<MyPage />} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
얘넨 요렇게 묶어줄 수 있겠죵
만약에 사용자가
마지막으로 경로를 변경해줄 Link
얘도 HTML 5 History API를 이용해 페이지의 주소만 변경해줍니다.
a태그를 사용해버리면 페이지를 전환하는 과정에서 리렌더링이 일어나기 때문에
Link 컴포넌트를 이용하면 쉽게 구현을 할 수 있겠죵
<Link to = "/dashboard" > dashboard</Link>
요렇게 to 속성을 활용해서 Route 컴포넌트에 설정해준 path 요소와 연결해줄 수 있어요
요 컴포넌트들을 사용하려면 React Router 라이브러리에서 얘네를 불러와야합니다.
이제 실습을 통해 알아봐요
🥶 리액트 라우터 실습하기
npm install yarn
yarn create react-app router-tutorial
cd router-tutorial
yarn add react-router-dom
열심히 인스톨해줄거 인스톨 해주고
{
"name": "router-tutorial",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^13.2.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.9.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.0"
},
제가 설치한 시점에선 6.9 버전으로 깔린것같네용
🌞프로젝트에 라우터 적용하기
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>,
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
index.js에 렌더 부분을
BrowserRouter로 묶어주면 굉장히 맛있게
묶어줄 수 있네요
당연히 BrowserRouter를 불러와야 쓸 수 있으니
import하는거 까먹지 마세요
전 까먹었음
src/pages/Home.js
import React from 'react';
const About = () => {
return (
<div>
<h1>thro</h1>
<h1>리액트라우터사용 About</h1>
</div>
);
};
export default About;
src/pages/About.js
import React from 'react';
const Home = () => {
return (
<div>
<h1>홈</h1>
<p>맨 먼저 보일 사이트</p>
</div>
);
};
export default Home;
보여줄 페이지를 간단하게 만들어줍니다.
단순 페이지를 위한 컴포넌트니까 따로 분리해주면 가독성이 좋겠네요
그래서 폴더를 하나 따로 만들어줬습니다.
이제 App.js로 돌아갑시다.
App.js
import React from 'react';
import { Route, Routes } from 'react-router-dom';
import About from './pages/About';
import Home from './pages/Home';
const App = () => {
return (
<Routes>
<Route path="/" element={<Home />}></Route>
<Route path="/about" element={<About />}></Route>
</Routes>
);
};
export default App;
항상 Route 컴포넌트는 Routes 컴포넌트의 자식으로 넣어줄 것
path에 /만 넣어주면 그게 디폴트로 보일 페이지가 되는것이네요!
실행결과를 창에서 보겠습니다.
path를 /로 지정해준 홈 컴포넌트만 렌더링되고 있는걸 확인할 수 있네요
오.. 대충 감이 오는데
😋Route 컴포넌트 문법과 Link 문법
<Route path="주소규칙" element={보여줄 컴포넌트 JSX}
path 넣어주고 사용하면 된다. 맛있다.
path에 '/'을 넣어주면 최초에 보여지는 페이지가 됨
<Link to={'/about'}>소개</Link>
link에는 path 대신 to가 들어갑니다.
to에 매치되는 path와 연결됩니다.
Link 컴포넌트에 넣어준 소개를 클릭하면 경로가 바뀌어서 다른게 렌더링 되네요
good
🤢url 파라미터와 쿼리스트링
페이지 주소를 정의할 때 가끔은 유동적인 값을 사용해야 할 때도 있습니다.
url 파라미터 예시 : /profile/velopert
쿼리스트링 예시 : /articles?page=1&keyword=react
쿼리 스트링은 간단히 보면 사용자가 입력 데이터를 전달하는 방법 중의 하나인데
url 주소에 미리 협의된 데이터를 파라미터를 통해 넘기는 것입니다.
따라서 위 예시에서 '?'뒤에 오는 내용이 쿼리스트링입니다.
? 키1 = 값 과 같이 key , value 쌍 형식으로 구성되어있고 여러개를 쓰려면 &을 사용한다.
aha 대충은 알겠읍니다.
사용법을 보죠
🤮URL 파라미터 사용법 useParams
import React from 'react';
import { useParams } from 'react-router-dom';
const data = {
velopert: {
name: '김민재',
description: '미친 개발자',
},
jisu: {
name: '류지수',
description: '폼이 미친 개발자',
},
};
const Profile = () => {
const params = useParams();
const profile = data[params.username];
return (
<div>
<h1>사용자프로필</h1>
{profile ? (
<div>
<h2>{profile.name}</h2>
<p>{profile.description}</p>
</div>
) : (
<p>존재하지 않는 프로필입니다.</p>
)}
</div>
);
};
export default Profile;
URL 파라미터는 useParams 라는 Hook을 사용해서 객체 형태로 조회할 수 있습니다.
URL 파라미터의 이름은 라우터 설정을 할 때
Route 컴포넌트의 path props를 통해 설정합니다.
useParams이라는 훅을 사용해줄건데
이건 React Router v5 이상에서 제공되는 훅이라고 합니다.
URL의 동적인 세그먼트에 매칭되는 값을 가져오기 위해 사용된다는데
useParams()를 호출해서 매개변수를 가져올 수 있고
이 hook은 객체를 반환합니다.
솔직히 잘 감이 오지가 않네요
aha!!!!!!
App.js에서 이렇게
<Routes>
<Route path="/" element={<Home />}></Route>
<Route path="/about" element={<About />}></Route>
<Route path="/profiles/:username" element={<Profile />}></Route>
</Routes>
URL 파라미터를 설정해주면서 Route 컴포넌트의 path prop에 들은
:username을 기준으로 비교를 하는데
요 username을
useParams를 쓰는 단에서 사용해주는거군요!!
okay... 그러면
const data = {
velopert: {
name: '김민재',
description: '미친 개발자',
},
jisu: {
name: '류지수',
description: '폼이 미친 개발자',
},
};
const Profile = () => {
const params = useParams();
const profile = data[params.username];
return (
<div>
<h1>사용자프로필</h1>
{profile ? (
<div>
<h2>{params.username}</h2>
<h2>{profile.name}</h2>
<p>{profile.description}</p>
</div>
) : (
<p>존재하지 않는 프로필입니다.</p>
)}
</div>
);
};
요 단에서 params의 username을 받아오는데..
객체안에 객체가 있는 구조니까
data에서 키값이 params.username인애를 뽑아서 profile에 할당시키고
실제로 출력을 하는건 즉 쭉 늘려서 썼을 때
data[params.username].name과 data[params.username].description 인거군요!!
아하.... 정말 멋지네요
🐶쿼리스트링은 useLocation
About.js
import React from 'react';
import { useLocation } from 'react-router-dom';
const About = () => {
const location = useLocation();
return (
<div>
<h1>thro</h1>
<h1>리액트라우터사용 About</h1>
<p>쿼리스트링 {location.search}</p>
</div>
);
};
export default About;
사용법은 다음과 같습니다. 그냥 호출만하면되네요?
useLocation 훅은 location 객체를 반환해줍니다.
이 객체에는 요런 값들이 담겨있어요
pathname | 현재 주소의 경로(쿼리스트링 제외) |
search | 맨 앞의 ? 문자를 포함한 쿼리스트링 값 |
hash | 주소의 #문자열 뒤의 값 |
state | 페이지로 이동할 때 임의로 넣을 수 있는 상태값 |
key | location 객체의 고유값 초기에는 default고 페이지가 변경될 때마다 고유의 값이 생성됨 |
http://localhost:3000/about?detail=true&mode=1
그래서 이런 쿼리스트링을 만들어서 이동해보면...?
잘되네용
so cool
http://localhost:3000/about?detail=true&mode=1
여기서 쿼리스트링 값은 ?detail=true & mode=1입니다.
이 문자열에서 앞에 있는 ?를 지우고
&문자열을 기준으로 분리 한 다음 key = value를 파싱하는 작업을 원래는 해줘야하는데..
요 파싱 작업을 하려면 귀찮은 정규식도 써야 편할테고
=기준으로 key value 파싱도 해줘야할테고... 스플릿도해줘야할테고
정말 귀찮겠다 그죵
그래서 이걸 해결해줄 useSearchParams라는 훅이 있다고 합니다.
😑useSerchParams를 사용해서 쿼리스트링을 쉽게 파싱해
import React from 'react';
import { useSearchParams } from 'react-router-dom';
const About = () => {
const [searchParams, setSearchParams] = useSearchParams();
const detail = searchParams.get('detail');
const mode = searchParams.get('mode');
const onToggleDetail = () => {
setSearchParams({ mode, detail: detail === 'true' ? false : true });
};
const onIncreaseMode = () => {
const nextMode = mode === null ? 1 : parseInt(mode) + 1;
setSearchParams({ mode: nextMode, detail });
};
return (
<div>
<h1>소개</h1>
<h1>리액트라우터사용 About</h1>
<p>detail : {detail}</p>
<p>mode : {mode}</p>
<button onClick={onToggleDetail}> Toggle Detail</button>
<button onClick={onIncreaseMode}> mode + 1</button>
</div>
);
};
export default About;
useSearchParams는 배열타입의 값을 반환하는데
첫번째 원소 | 쿼리파라미터를 조회,수정하는 메서드가 담긴 객체 (getmethod와 setmethod도 존재함) 만약 get으로 조회했을때 쿼리파라미터가 존재하지 않으면 null로 조회됨 |
두번째 원소 | 쿼리파라미터를 객체 형태로 업데이트할 수 있는 함수 |
각각 이렇게 값을 준다고 합니다.
const detail = searchParams.get('detail');
const mode = searchParams.get('mode');
그래서 요렇게 get메서드로 뭔가를 가져올 수 있는거군요
아니 근데 왜 null이 나와야하는데 NaN이 나옴?
진짜 어이없다
http://localhost:3000/about?mode=9&detail=true
주소값에 mode를 제대로 할당해주는 것으로 오류찾기 완료..
나는 멍청이야
쿼리파라미터를 사용할 때 주의할 점
값이 무적권 문자열 타입이라는 거임
그래서 위 코드에서도 값은 불린타입으로 넣어주는데
detail === 'true'로 비교하는 이유가
값이 무적권 문자열 타입으로 들어오기 때문
따라서 숫자를 다룰때도 parseInt나 Number를 통해서 변환해줘야겠네요
👽중첩된 라우터를 만들어보자.
정말 멋지네요 이 중첩은 어케 만드냐
Articles.js
import React from 'react';
import { Link } from 'react-router-dom';
const Articles = () => {
return (
<ul>
<li>
<Link to={'/articles/1'}>게시글 1</Link>
</li>
<li>
<Link to={'/articles/2'}>게시글 2</Link>
</li>
<li>
<Link to={'/articles/3'}>게시글 3</Link>
</li>
</ul>
);
};
export default Articles;
Articles.js에서 링크 컴포넌트를 만들어줍니다.
Article.js
'react' 카테고리의 다른 글
React.lazy와 코드스플리팅 (0) | 2023.04.18 |
---|---|
immer를 이용해 깊은 복사를 케이크처럼 간단히 먹자 (1) | 2023.04.08 |
react-virtualized 를 사용한 렌더링 최적화를 해보자 (0) | 2023.04.06 |
리액트의 Context API를 알아보자.. (0) | 2023.04.04 |
useEffect를 async와 함께 사용할 때 유의할 점 (0) | 2023.03.31 |