페이지 주소를 정의할 때, 유동적인 값을 전달해야할 때가 있다. 이럴때 파라미터와 쿼리로 나뉘어질 수 있다.
파라미터 - 특정 id나 이름을 가지고 조회할 때 사용
쿼리 - 특정 키워드 검색하거나, 요청할 때 필요한 옵션을 전달할 때 사용된다.
Profile.js
를 만들어서 url 파라미터를 조회한다 이때 profile 함수에서는 match라는 props를 받아오게 되는데, route에 따로 작성하지 않아도 자동으로 받아온다.
import React from "react";
const profileData={
profileName: {
name: '아무개',
description: '아무렇게나 사는 아무개'
},
homer:{
name: '호머 심슨',
description: '심슨 가족에 나오는 아빠 역할 캐릭터'
}
}
function Profile({match}) {
return (
<div>
Hello React!
</div>
);
}
export default Profile;
username의 값을 받아게 해보자. match 라는 props 에는 params라는 값이 있는데 이안에 작성자가 넣어주고 싶은 url파라미터가 들어있다.
import React from "react";
import { useParams } from "react-router-dom";
const profileData={
profileName: {
name: '아무개',
description: '아무렇게나 사는 아무개'
},
homer:{
name: '호머 심슨',
description: '심슨 가족에 나오는 아빠 역할 캐릭터'
}
}
function Profile({match}) {
const { username } = useParams();
const profile = profileData[username]
if (!profile) {
return <div>없는 사람인데?</div>
}
return (
<div>
<h3>{username} ({profile.name})</h3>
<p>
{profile.description}
</p>
</div>
);
}
export default Profile;
react-router-dom 버전 6부터는 element로 컴포넌트를 만들고, route props(match, history, location)을 받지 않는다. 따라서, useParams, useLocation, useHistory를 사용하여 route context에 접근한다.
출처 : https://velog.io/@kcdoggo/Cannot-read-property-params-of-undefined-%EC%97%90%EB%9F%AC
App의 렌더링 내용을 수정한다.
import React from "react";
import {Route, Routes, Link} from 'react-router-dom';
import Home from "./Home";
import About from "./About";
import Profile from "./Profile";
function App() {
return (
<>
<ul>
<li>
<Link to="/">홈</Link>
</li>
<li>
<Link to='/about'>소개</Link>
</li>
</ul>
<hr/>
<Routes>
<Route path="/" element={<Home/>}/>
<Route path="/about" element={<About/>}/>
<Route path="/profile/:username" element={<Profile/>}/>
</Routes>
</>
);
}
export default App;
실행하고 주소창에 profile/(ProfileData안에 작성한 객체 이름 하나)를 적어서 입력해보자. 작성자의 경우 profileName
을 적어넣었다.
http://localhost:3000/profile/profileName
으로 적고 들어가면
이렇게 이름과 설명이 나타나게 된다.
이제 profile페이지로 이동할 수 있도록 Home
페이지에 Link
를 더 만들어보자.
function Home() {
return (
<div>
<h1>홈</h1>
<p>가장 먼저 보이는 페이지입니다.</p>
<ul>
<li>
<Link to="/about">소개</Link>
</li>
<li>
<Link to="/profiles/profileName">profileName의 프로필</Link>
</li>
<li>
<Link to="/profiles/homer">homver의 프로필</Link>
</li>
<li>
<Link to="/profiles/void">존재하지 않는 프로필</Link>
</li>
</ul>
</div>
);
}
라우트에서 쿼리스트링을 사용하는 방법을 알아본다. 쿼리스트링을 사용할 때는 URL 파라미터와 달리 Route 컴포넌트를 사용할때 별도로 설정해야하는 것은 없다.
import React from "react";
import { useLocation } from "react-router-dom";
function About() {
const location =useLocation();
return (
<div>
<h1>소개</h1>
<p>이 프로젝트는 리액트 라우터 기초를 실습하는 예제입니다.</p>
<p>쿼리스트링: {location.search}</p>
</div>
);
}
export default About;
위 코드처럼 useLocation
이라는 Hook을 사용해서 작정했다. useLocation
은 location객체를 반환하며 현재 사용자가 보고있는 페이지의 정보를 지니고 있고, 다음과 같은 값들이 존재한다.
location.serach
로 쿼리스트링 값을 출력할수 있는데, about페이지 url뒤에 ?detail=true&mode=1 입력한뒤 enter를 누르면
이렇게 ?뒤의 쿼리스트링이 나타나게 된다. 해당 문자열에서 앞에있는 ?를 지우고 &문자열로 분리한 뒤 key와 value를 파싱하는 작업을 하면 해당 쿼리스트링의 조건에 따라 다른 출력값을 가지게 할수 있다.
쿼리스트링을 따로 파싱하기 위해서는 useSearchParams
라는 Hook을 사용한다.
import React from "react";
import { useSearchParams } from "react-router-dom";
function About() {
const [searchParams, setSeratchParams] = useSearchParams();
const detail = searchParams.get('detail');
const mode = searchParams.get('mode');
function onToggleDetail() {
setSeratchParams({ detail:detail ==='true'? false: true , mode});
};
function onIncreaseMode() {
const nextMode = mode === null? 1 :parseInt(mode) + 1;
setSeratchParams({detail , mode: nextMode});
}
return (
<div>
<h1>소개</h1>
<p>이 프로젝트는 리액트 라우터 기초를 실습하는 예제입니다.</p>
<p>deratil:{detail}</p>
<p>mode: {mode}</p>
<button onClick={onToggleDetail}>Toggle detail</button>
<button onClick={onIncreaseMode}>mode + 1 </button>
</div>
);
}
export default About;
onToggleDetail
함수를 호출하는 버튼을 누르면 detail의 값이 true/false로 변경된다.
onIncreaseMode
함수를 호출하는 버튼을 누르면 mode가 가지고 있는 값을 현재 값에 1을 더한 값으로 변경하며, 이때 mode값이 없으면 null로 변경한다.useSearchParams
는 배열 타입의 값을 반환한다. 조회할때 쿼리파라미터가 존재하지 않는다면 null로 조회된다.
쿼리파라미터를 사용할 때 주의할점은 쿼리 파라미터를 조회할 때 값은 무조건 문자열 타입이라는 것이며, true
또는 false
값을 넣게 된다면 값을 비교할 때 꼭 true
와 같이 따옴표로 감싸서 비교를 해야하며, 숫자를 다루게 된다면 parseInt를 사용해서 숫자타입으로 변환을 해야한다.