본문 바로가기

프론트앤드 수업

[React] 라우터(페이지 이동), 쿼리스트링 , useLocation

728x90

리액트 라우터

페이지이동
* 기존 방식은 여러개의 페이지를 사용해 새로운 페이지를 로드하는방식
이동

* 리액트는 spa 방식으로 새로운 페이지를 로드하지 않고 하나의 페이지 안에서
필요한 데이터만 가져오는 형태를 가진다.
라우팅
사용자가 요청한 url에 따라 해당 url에 맞는 페이지를 보여주는것.

* React-Router : 신규페이지를 불러오지 않는 상황에서 각각의 url에 따라 선택된 데이터를 하나의 페이지 에서 렌더링 해주는 라이브러리.

https://reactrouter.com/
설치방법
npm install react-router-dom

BrowserRouter으로 main.jsx를 감싸줘야한다.
Routers로 묶고나서 사용. v5.0때는 switch .

실습, 메인페이지

function App() {
  return (
    <BrowserRouter>
    <div className="App">
      <Header/>
      {/* Routes컴포넌트는 여러 Route를 감싸서 그 중 url이 일치하는 라우트 단 하나만 랜더링 시켜줌 
        Route는 Path 속성에 el*/}
      <Routes>
        <Route path="/Main" element={<Main/>}/>
        <Route path="/product/:productId/:productName" element={<Product/>}/>        
        <Route path="/detail" element={<DetailProduct/>}>
          <Route path="detail1" element={<Detail1/>} />
          <Route path="detail2" element={<Detail2/>} />
      </Route>       
      <Route path="info/*" element={<Info/>} />
        {/* 상단에 위치하는 경로를 모두 확인, 일치하는 경로가 없는경우 처리 */}
        <Route path="*" element={<NotFound/>}/>   
      </Routes>
    </div>
    </BrowserRouter>
  );

*은 상단에 위치하는 경로를 모두 확인하고 일치하는 경로가 없는경우에 처리한다.

URL파라미터
- 사용방법 : 경로에 : 사용해서 설정
Ex ) /product/:productId

// 1이 productId에 담긴다.

최 상단에 BrowserRouter을 감싼 후 사용이 가능하다.

라우터에 엘리멘트로 입력 후 해당파일에서 Link to로 사용이 가능하다.

import { Link } from 'react-router-dom'
링크 선언 후 사용가능

    메인페이지
            <ul>
                <li><Link to="/product/1/신발?search=procuctname&q=dome#test">1번상품</Link></li>
                <li><Link to="/product/2/노트북?search=green&q=abc#test2">2번상품</Link></li>
            </ul>

메인페이지에서 전에 썻던 get 방식으로 값을 보내주고 있다. 모든 값을 받기위해서는 useLocation문이 필요하지만,

가벼운 쿼리스트링문만을 받기에는 useParms 만으로도 사용 할 수 있다.

import { useParams, useLocation } from 'react-router-dom'
  const { productId, productName } = useParams();
     {productId}번 상품페이지 입니다.
     <div>{productName} 상품 페이지 </div>
       Params 사용
      const location = useLocation();
          <li>hash : {location.hash}</li>
          <li>pathname : {location.pathname}</li>
          <li>search : {location.search}</li>
          <li>key : {location.key}</li>

1번상품</Link\>

product 다음나오는 1과 신발이 값이 파라미터값이되고 params는 이 값을 받아올 수 있다.

App페이지의 Route선언중 produce/:이름1/:이름2 의 방식으로 이름을 받아올 수 있다.

useLocation 같은 경우에는 모든 쿼리스트링 값을 다 받아올 수 있다. useLocation 선언 후 함수에 로케이션을 담을시 쿼리스트링 값을 가지고 있는 객체로 반환되며 값 들은 각각의 이름이 담겨있다. 위의 값을 보고 비교 할 수 있고 정리하면

hash : #뒤에있는 값

pathname : 현재 주소 경로

search : ?뒤에있는 쿼리스트링값

key : location 객체의 고유 값, 초기값은 default, 페이지가 변경될때마다 변경되기에 랜덤값으로 보면 된다.

<li><NavLink to="/Main" className={({isActive})=> isActive ? "okay" : ""}>메인페이지</NavLink></li>
<li><NavLink to="/product/*/*" className={({isActive})=>"green " + (isActive ? "okay" : "")}>상품페이지</NavLink></li>
 <li><NavLink to="/detail">자세히보기</NavLink></li>
<li><NavLink to="/detail/detail1">1번상품보기</NavLink></li>
<li><NavLink to="/detail/detail2"}>2번상품보기</NavLink></li>
<li><NavLink to="/info">info 정보보기</NavLink></li>

링크 클릭시 컴포넌트에 Active클래스를 붙여준다.
* 클릭한 링크의 스타일을 지정할 수 있다.

기본적으로 isActive 가 붙지만 ClassName을 이용해 다른이름을 넣을수있다. '각각 스타일을 지정 할 수 있다'


중첩라우팅 사용방법

1번상품보기를 누를시 자세히보기가 위에있고 그 밑에 상세보기가 나타난다.

방법1. Outlet 사용

detail 파일을 자세히보기 메뉴로두고 detail1과 dedatil2를 생성했다.

     <Route path="/detail" element={<DetailProduct/>}>
              <Route path="detail1" element={<Detail1/>} />
              <Route path="detail2" element={<Detail2/>} />
         </Route>    

그리고 메인이될 detail의 Route를 끊지 않고 그사이에 Route값을 넣어준다.

Detail1과 2의 파일엔 그냥 쓰고싶은 말만 입력하면 되고 그 부모요소에만 Outlet를 입력해준다.

import React from 'react';
import { Outlet } from 'react-router-dom';

const DetailProduct = () => {
    return (
        <div>
            상품 자세히 보기
            <Outlet/>
        </div>
    );
};

export default DetailProduct;

2. 부모 Route의 path 마지막에 /*을 표시 ==> 중첩 라우터의 사용을 명시적으로 표시 자식 라우터는 부모 라우터 컴포넌트 안에 작성

      <Route path="info/*" element={<Info/>} />

메인인 App에서는 이렇게 표시되어있다.
파일은 Info, Info1, Info2 이다. 마찬가지로 1과 2에는 필요한내용만 적어놓고 부모요소에만 추가를 하면 된다.

import React from 'react';
import { Link, Route, Routes } from 'react-router-dom';
import Info1 from './Info1';
import Info2 from './Info2';

const Info = () => {
    return (
        <div>
           정보 페이지 입니다.
           <div>
                <Link to="info1">정보1</Link>
                <Link to="info2">정보2</Link>
           </div>
           <Routes>
                    <Route path="info1" element={<Info1/>}/>
                    <Route path="info2" element={<Info2/>}/>
                    <Route/>    
            </Routes>  
        </div>
    );
};

export default Info;

Link to로 링크를 걸어주고 부모요소안에서 Routes를 그대로 생성하도록 한다.

728x90
댓글