리액트 라우터 - 파라미터와 쿼리

정영찬·2022년 3월 8일
0

리액트

목록 보기
45/79

페이지 주소를 정의할 때, 유동적인 값을 전달해야할 때가 있다. 이럴때 파라미터와 쿼리로 나뉘어질 수 있다.

파라미터 - 특정 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객체를 반환하며 현재 사용자가 보고있는 페이지의 정보를 지니고 있고, 다음과 같은 값들이 존재한다.

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

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를 사용해서 숫자타입으로 변환을 해야한다.

profile
개발자 꿈나무

0개의 댓글