본문 바로가기
JavaScript/React

React) 리액트 라우터로 SPA 개발하기 - URL 파라미터와 쿼리스트링 (useParams, useLocation, useSearchParam Hook)

by 박채니 2022. 11. 23.
안녕하세요, 코린이의 코딩 학습기 채니 입니다.
[리액트를 다루는 기술]의 책을 참고하여 포스팅한 개인 공부 내용입니다.

 

리액트 라우터로 SPA 개발하기

 

URL 파라미터와 쿼리스트링

  • URL 파라미터 예시 : /profile/chany
  • 쿼리 스트링 예시 : /articles?page=1&keyword=react

이처럼 페이지 주소를 정의할 때 유동적인 값을 사용해야할 때가 많습니다.

 


URL 파라미터

 

  • 주소 경로에 유동적인 값을 넣는 형태
  • 주로 ID 또는 이름을 사용해 특정 데이터를 조회할 때 사용

 

src/pages/Profile.js

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

const data = {
    chany: {
        name: '박채니',
        description: '리액트를 잘하고 싶은 개발자'
    },
    gildong: {
        name: '홍길동',
        description: '고전 소설 홍길동전의 주인공'
    }
};

const Profile = () => {
    const params = useParams();
    console.log(params); // {username: 'chany'} || {username: 'gildong'} || {username: 'void'}
    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를 통해 설정합니다.

 

위 코드는 username URL 파라미터를 통해 프로필을 조회하고, 존재하지 않는다면 '존재하지 않는 프로필입니다.'를 출력해주며, 존재한다면 해당 profile의 정보를 렌더링 해줍니다.

 

App.js

import './App.css';
import Home from './pages/Home';
import About from './pages/About';
import { Routes, Route } from 'react-router-dom';
import Profile from './pages/Profile';

function App() {
  return (
    <Routes>
      <Route path='/' element={<Home />} />
      <Route path='/about' element={<About />} />
      <Route path='/profiles/:username' element={<Profile />} />
    </Routes>
  );
}

export default App;

URL 파라미터'/profiles/:username'과 같이 경로에 ':'를 사용하여 설정해줍니다.

※ URL 파라미터가 여러 개인 경우

'/profiles/:username/:field'와 같은 형태로 사용!

 

src/pages/Home.js

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

const Home = () => {
    return (
        <div>
            <h1>홈</h1>
            <p>가장 먼저 보여지는 페이지입니다.</p>
            <ul>
                <li>
                    <Link to="/about">소개</Link>
                </li>
                <li>
                    <Link to="/profiles/chany">chany의 프로필</Link>
                </li>
                <li>
                    <Link to="/profiles/gildong">gildong의 프로필</Link>
                </li>
                <li>
                    <Link to="/profiles/void">존재하지 않는 프로필ㅌ</Link>
                </li>
            </ul>
        </div>
    )
}

export default Home;

URL에 따라 프로필이 잘 확인됩니다.

 

쿼리스트링

 

쿼리스트링을 별도 설정해야하는 것이 없으며, 화면에 렌더링 시켜보겠습니다.

 

src/pages/About.js

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

const About = () => {
    const location = useLocation(); // {pathname: '/about', search: '', hash: '', state: null, key: 'avlqnm6v'}

    return (
        <div>
            <h1>소개</h1>
            <p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
            <p>쿼리스트링 : {location.search}</p>
        </div>
    )
}

export default About;

useLocation Hooklocation 객체를 반환하고, 해당 객체에는 아래와 같은 값들이 담겨있습니다.

 

  • pathname : 현재 주소의 경로 (쿼리스트링 제외)
  • search : 맨 앞의 ? 문자를 포함한 쿼리스트링 값
  • hash : 주소의 # 문자열 뒤의 값 (구형 브라우저에서 클라이언트 라우팅 사용 시 쓰는 해시 라우터 사용)
  • state : 페이지로 이동할 때 임의로 넣을 수 있는 상태 값
  • key : location 객체의 고유값, 초기에는 default이며 페이지가 변경될 때마다 고유의 값 생성

 

location.search를 통해 쿼리스트링을 확인할 수 있습니다.

위처럼 쿼리 스트링이 출력되는 것을 확인할 수 있습니다.

 

이제 문자열 앞에 있는 ?를 지우고 &를 기준으로 key=value값을 파싱해야하는데요,

useSearchParam Hook을 이용해 작업하겠습니다.

 

src/pages/About.js

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

const About = () => {
    const [searchParams, setSerachParams] = useSearchParams();
    const detail = searchParams.get('detail');
    const mode = searchParams.get('mode');

    const onToggleDetail = () => {
        setSerachParams({ mode, detail: detail === 'true' ? false : true});
    };

    const onIncreaseMode = () => {
        const nextMode = mode === null ? 1 : parseInt(mode) + 1;
        setSerachParams({mode: nextMode, detail});
    }
    
    return (
        <div>
            <h1>소개</h1>
            <p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
            <p>detail : {detail}</p>
            <p>mode : {mode}</p>
            <button onClick={onToggleDetail}>Toggle detail</button>
            <button onClick={onIncreaseMode}>mode + 1</button>
        </div>
    )
}

export default About;

Toggle detail 버튼 클릭 시 (기본 값 true)
mode + 1 클릭 시 (기본 값 1)

useSearchParam

- 배열 타입의 값 반환

- 첫 번째 원소는 쿼리파라미터를 조회하거나 수정하는 메소드들이 담긴 객체를 반환

- get 메소드를 통해 특정 쿼리파라미터 조회

- set 메소드를 통해 특정 쿼리파라미터 업데이트

- 조회 시 쿼리파라미터가 존재하지 않는다면 null로 조회

- 두 번째 원소는 쿼리파라미터를 객체 형태로 업데이트 할 수 있는 함수를 반환

 

☆ 쿼리파라미터를 조회할 때 값은 무조건 문자열 타입이기 때문에 'true'처럼 따옴표로 감싸주고 숫자는 parseInt 사용!