📢 어렵고 정석적인 개념 설명보다는 저같은 초보자도 이해하기 쉽게 정리하는 것을 원칙으로 포스팅하고 있습니다. 😄

[React] React Router를 이용하여 페이지 이동하기

준비

우리가 리액트를 사용하는 이유는 간단하다. 바로 싱글 페이지 애플리케이션(SPA)이 웹 개발에서 매우 효율적이기 때문이다. SPA가 무엇인지 간단히 설명하자면 원래 사이트 간 이동을 할 때 새로고침 하듯이 깜박거리며 사이트가 이동하는 게 일반적이었다. 하지만, 이는 속도나 서버 가성비 측면에서 매우 비효율적인 방법이었고, 이를 극복하기 위해 리액트같은 프레임워크가 등장하면서 사이트 이동 시 필요한 부분만 효율적으로 받아서 출력하는 방식으로 바뀌게 된 것이다.

 

$ npm install react-router-dom --save

앞에서 말한 SPA를 만들기 위해서 React Router라는 라이브러리를 먼저 설치해주어야 한다.

 

방법

컴포넌트 경로 설정하기

import {BrowserRouter, Routes, Route} from 'react-router-dom';

function App() {
    return <div>
    	<h1>이 부분은 바뀌지 않습니다.</h1>
        <BrowserRouter>
            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/New" element={<New />} />
                <Route path="/Edit" element={<Edit />} />
                <Route path="*" element={<NotFound />} />
            </Routes>
        </BrowserRouter>
    </div>
}

이 SPA의 컴포넌트는 총 3개(Home, New, Edit)이라고 가정하겠다. 컴포넌트는 큰 사이트를 이루고 있는 사이트 조각이라고 생각하면 된다. 이제 각 컴포넌트마다 라우팅 경로를 설정해주어야 한다. 쉽게 말해 주소창에 "www.shawnkim.com"라고 치면 Home 컴포넌트가 나오고, "www.shawnkim.com/new"라고 치면 New 컴포넌트가 나오는 식이다.

 

1) <BrowserRouter>로 전체를 감싸주어야 한다. 경로를 인식하는 역할을 담당한다.

2) 그 밑에 <Routes>로 컴포넌트 경로를 또 한 번 묶어준다. switch문의 switch 역할을 한다.

3) 최종적으로 컴포넌트들의 경로를 <Route>를 이용해 설정해주면 된다. switch문의 case 역할을 한다.

 

<Route>를 사용할 때는 path와 element 속성을 사용한다. path주소창에 입력될 값(경로)을 넣어주면 되고, elementpath로 등록된 값을 넣었을 때 출력되는 컴포넌트를 넣어주면 된다.

 

만약, 따로 정하지 않는 path 값을 넣었을 경우에 Not Found 페이지로 이동시키고 싶다면 path에 '*'를 줘서 임의의 경로로 접근했을 때 NotFound 컴포넌트가 뜨도록 설정할 수 있다.

 

Link를 통해 경로 이동하기

const RoutesLink = () => {
    return <>
        <Link to="/">Home으로 이동</Link>
        <Link to="/new">New로 이동</Link>
        <Link to="/edit">Edit으로 이동</Link>
    </>
}

export default RoutesLink;
import {BrowserRouter, Routes, Route} from 'react-router-dom';

function App() {
    return <div>
        <BrowserRouter>
            <RoutesLink />
        </BrowserRouter>
    </div>
}

HTML에서 <a> 태그를 통해 사이트 간 이동을 했다면, 리액트에서는 Link를 이용하여 컴포넌트 간 이동을 할 수 있다.

만약 사이트 주소가 "www.shawn.com"이라고 한다면, <Link to={"/new"} />를 클릭했을 시 "www.shawn.com/new"로 이동하게 되는 것이다. 즉, Link는 주소창에 직접 입력하는 것 대신 클릭 시에 해당 컴포넌트의 경로를 주소창에 넣어주는 역할을 대신 해주는 셈이다. (ex. 로그인 하지 않은 상태에서 '내 정보'를 클릭했을 때 로그인 페이지로 강제 이동시킬 때)

 

CSR 페이지 라우팅 설정

URL Parameter (useParams)

import {BrowserRouter, Routes, Route} from 'react-router-dom';

function App() {
    return <div>
    	<h1>이 부분은 바뀌지 않습니다.</h1>
        <BrowserRouter>
            <Routes>
                <Route path="/New/:id" element={<New />} />
            </Routes>
        </BrowserRouter>
    </div>
}
import {useParams} from "react-router-dom";

const New = () => {
    // 둘 중 한 가지 방식으로 선언해주면 된다.
    const {id} = useParams();
    const params = useParams();
    
    return <div>
        <h1>New 페이지입니다. {id} 혹은 {params.id}</h1>
    </div>
}

"www.shawn.com/new/1" 이런 식으로 new 컴포넌트 뒤에 숫자가 붙은 형태의 사이트를 본 적 있을 것이다.

1과 같이 뒤에 붙는 값을 URL Parameter이라고 하는데, 여기서 우리는 id라고 설정했다. (New/:id 이런 식으로 설정)

 

보통 const params = useParams(); 로 선언하며 객체를 반환한다. params 객체는 아까 <Route path="/New/:id" />에서 설정한 id가 객체의 key 값으로 들어간다. 따라서, params.id 혹은 구조분해할당을 통해 {id}로 URL Parameter 값을 꺼내올 수 있다.

 

Query String (useSearchParams)

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

const Edit = () => {
    const [searchParams, setSearchParams] = useSearchParams();

    const id = searchParams.get("id");
    const mode = searchParams.get("mode");
    
    return <div>
        <h1>Edit 페이지입니다.</h1>
        <button onClick={() => setSearchParams({id: "shawn"})}></button>
    </div>
}

Query String이란 페이지에 간단하게 데이터를 전달하는 방법으로, "www.shawn.com/?id=123&mode=dark이런 도메인이 있을 때 최종 경로 뒤에 물음표와 함께 붙는 형식을 말한다.

 

useState()처럼 useSearchParams()를 비구조화 할당을 통해 선언해주고, id와 mode의 값을 각각 가져오도록 선언해주면 된다. const id = searchParams.get("id")를 풀어서 설명하자면, 변수 id는 "www....~~/?id=123"에서 id 값인 123을 가져온다는 뜻이 된다. 또한 setSearchParams()를 통해 새로운 값을 집어넣을 수도 있는데, 버튼을 누르면 id에 "shawn"을 집어넣어서 "www...~~/?id=shawn"이 된다.

 

Page Moving (useNavigate)

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

const Home = () => {
    const navigate = useNavigate();

    return <div>
        <h1>New 페이지입니다.</h1>
        <button onClick={() => navigate("/new")}>New로 이동</button>
        <button onClick={() => navigate("/edit")}>Edit으로 이동</button>
        <button onClick={() => navigate(-1)}>뒤로 이동</button>
    </div>
}

Link 대신 useNavigate()를 이용하여 사이트를 이동할 수 있는데, 먼저 useNavigate()를 통해 navigate라는 이름의 함수를 선언해주고 각 버튼을 클릭하면 해당 경로의 컴포넌트로 이동하게 된다.

Link는 마치 <a>태그처럼 DOM을 만들고 그것을 클릭하면 이동시키는 기능이였다면, navigate()는 함수로서 페이지 이동 역할을 수행한다.

 

1. npm install react-router-dom
2. <BrowserRouter> 안에 <Routes> 안에 <Route>
3. <Route path="/" element={<컴포넌트 />} />
4. "www.../1" -> const {id} = useParams();
5. "www.../?id=1&po=ma" -> const [searchParams, setSearchParams] = useSearchParams();
6. 의도적으로 컴포넌트 간 이동시킬 땐 <Link> 또는 useNavigate()