React-Router-dom v6

Minji Lee·2023년 4월 17일
0

frontend

목록 보기
3/5
post-thumbnail

React-Router-dom

: 클라이언트 측 라우팅 지원

  • 서버에서 다른 문서 다시 요청하지 않고 URL 업데이트
  • 더 빠른 사용자 경험 가능하게 함
// index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
// App.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";

const router= createBrowserRouter([
  {
    path: '/',
    element: <Root />,
    errorElement: <ErrorPage />,
    children: [
      {path:'/', element:<Main />},
			{path:'/profile', element:<Profile />},
    ]
  }
]);

function App() {
  return (
    <>
      <RouterProvider router={router} />
    </>
  );
}

export default App;

Route 연결

Switch

: Route 구성을 감싸기 위한 부모 요소

→ react-router v6에서는 <Switch><Routes>로 변경
v5에서 사용되었을 때

<Router>
	<Switch>
		<Route exact path="/">
			<Main />
		<Route>
		<Route path="/profile">
			<Profile />
		</Route>
	</Switch>
</Router>

v6에서 사용되었을 때

<Routes>
	<Route exact path="/">
		<Main />
	<Route>
	<Route path="/profile">
		<Profile />
	</Route>
</Routes>

<Link>는 사용자가 클릭 하거나 탭 하여 다른 페이지로 이동할 수 있게 해주는 요소

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

function Main(){
	return(
		<Link to='/profile'>
			프로필
		</Link>
	);
}

History API

react-router-dom v6부터는 history, useHistory → useNavigate 교체

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

function Main(){
	const navigate = useNavigate();

	// 뒤로 가기
	const handleGoBack = () =>{
		navigate(-1);
	}

	//홈으로 가기
	const handleGoHome = () =>{
		navigate('/');
	}

	return(
		<>
			<button onClick={handleGoBack}>뒤로가기</button>
			<button onClick={handleGoHome}>홈가기</button>
		</>
	)
}

동적 라우팅

라우터의 경로에 유동적인 값 넣어서 특정 경로로 이동
URL 파라미터와 쿼리스트링으로 나눠짐

파라미터

주소의 경로에 유동적인 값을 넣는 형태 → /class/3

  • ID 또는 이름 사용하여 특정 데이터 조회하는 경우 사용
  • <Route path=”/class/:id” element={<Class />} />
  • const {id} = useParams(); → id는 파라미터에서 설정한 :뒤의 값
    ex)
// App.js
	<Router>
      <Routes>
        <Route element={<Header />}>
          <Route path="/" element={<Home />} />
        </Route>
        <Route path="/class" element={<Student />}>
          <Route path=":id" element={<Class />}>
            <Route path=":snum" element={<StudentDetail />} />
          </Route>
        </Route>
      </Routes>
    </Router>
// Student.js -> 반 목록 조회
import React from "react";
import { Link, Outlet } from "react-router-dom";

function Student() {
  return (
    <>
      <ul>
        <li>
          <Link to="/class/1">1반</Link>
        </li>

        <li>
          <Link to="/class/2">2반</Link>
        </li>

        <li>
          <Link to="/class/3">3반 </Link>
        </li>
      </ul>
      <hr />
      <Outlet />
    </>
  );
}

export default Student;
// Class.js -> 해당 반 정보와 학생 리스트
import React from "react";
import { useParams, Link, Outlet } from "react-router-dom";

function Class() {
  const { id } = useParams();

  console.log(id);
  return (
    <>
      <h1>이곳은 {id} 반 입니다.</h1>
      <h2>학생 정보</h2>
      <ul>
        <li>
          <Link to={`/class/${id}/1`}>kim</Link>
        </li>
        <li>
          <Link to={`/class/${id}/2`}>lee</Link>
        </li>
        <li>
          <Link to={`/class/${id}/3`}>park</Link>
        </li>
      </ul>
      <hr />
      <Outlet />
    </>
  );
}

export default Class;
// StudentDetail.js -> 해당 학생 상세정보 
import React from "react";
import { useParams, useNavigate } from "react-router-dom";

const studentData = {
  1: {
    name: "kim",
    sNum: 1,
    major: "computer",
  },
  2: {
    name: "lee",
    sNum: 2,
    major: "design",
  },
  3: {
    name: "park",
    sNum: 3,
    major: "nano",
  },
};

function StudentDetail() {
  const navigate = useNavigate();
  const { snum } = useParams();
  console.log(snum);
  const student = studentData[snum];
  return (
    <div>
      {student ? (
        <div>
          <h3>이름: {student.name}</h3>
          <div>학번: {student.sNum}</div>
          <div>전공: {student.major}</div>
        </div>
      ) : (
        <>
          <div>존재하지 않는 학생입니다.</div>
          <button onClick={() => navigate(-1)}>뒤로가기</button>
        </>
      )}
    </div>
  );
}

export default StudentDetail;




쿼리스트링

: 주소의 뒷부분에 ? 문자열 이후에 key=value로 값을 정의하며, &로 구분하는 형태

→ 키워드 검색, 페이지네이션, 정렬 방식 등 데이터 조회에 필요한 옵션 전달 시 사용
ex) /articles?page=1&keyword=react

  • useLocation()location객체 반환(현재 사용자가 보고 있는 페이지 정보)
  • ? 뒤로 & 문자열 기준으로 분리하여 key와 value 파싱하는 작업 해야함 → v6부터는 useSearchParams 훅 이용하면 편함 const [searchParams, setSearchParams]=useSearchParams();
  • get: 특정 쿼리파라미터 조회 const detail=serachParams.get(’detail’);
  • set: 특정 쿼리파라미터 업데이트 가능 setSearchParams({mode,detail:detail===’true’?false:true});
  • 조회시 쿼리 파라미터 없으면 null로 조회됨
  • 쿼리파라미터로 조회할 때는 무조건 문자열 타입! → 따옴표로 감싸기
    • true로 조회하면 안됨 → ‘true’
    • 숫자인 경우 문자열로 하고 parseInt사용하여 숫자 타입으로 변환

ex)

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

function About() {
  const [searchParams, setSearchParams] = useSearchParams();
  const user = searchParams.get("user");
  const keyword = searchParams.get("keyword");
  const page = searchParams.get("page");

  const changeIsUser = () => {
    setSearchParams({
      user: user === "true" ? false : true,
      keyword,
      page,
    });
  };

  const countPage = () => {
    const plusPage = page === null ? 1 : parseInt(page) + 1;
    setSearchParams({ user, keyword, page: plusPage });
  };

  return (
    <div>
      <h1>소개</h1>
      <p>쿼리스트링 react-router-dom v6</p>
      <p>유저인가요? {user}</p>
      <p>검색한 키워드: {keyword}</p>
      <p>페이지번호: {page}</p>
      <button onClick={changeIsUser} style={{ marginRight: "3rem" }}>
        유저여부 변경
      </button>
      <button onClick={countPage}>페이지번호증가</button>
    </div>
  );
}

export default About;

  • 유저여부 변경 버튼 클릭

  • 페이지 번호증가 버튼 두번 클릭


중첩라우트(Nested routes)

Outlet 컴포넌트 사용: Route의 childeren으로 들어가는 JSX 엘리먼트 보여주는 역할
ex)
1. 홈화면에 헤더 보이고 싶을 경우

// App.js
// 자식 컴포넌트 Route를 안에 감싼다.
function App() {
  return (
    <Router>
      <Routes> 
        <Route element={<Header />}>
          <Route path="/" element={<Home />} />
        </Route>
        <Route path="/class" element={<Student />}>
          <Route path=":id" element={<Class />} />
        </Route>
      </Routes>
    </Router>
  );
}
// Home.js
import React from "react";
import { Link } from "react-router-dom";

function Home() {
  return (
    <div>
      <h1>홈입니다.</h1>
      <Link to="/class">교실가기</Link>
    </div>
  );
}

export default Home;
// Header.js
import React from "react";
import { Outlet } from "react-router-dom";

// Outlet컴포넌트 사용하여 자식 컴포넌트 나오게끔
function Header() {
  return (
    <>
      <h1 style={{ background: "lime", width: "100%", height: "4rem" }}>
        헤더
      </h1>
      <Outlet />
    </>
  );
}

export default Header;

  1. 목록도 보이면서 해당 목록의 내용도 보이게끔
// Student.js -> 전체 반 정보 출력
import React from "react";
import { Link, Outlet } from "react-router-dom";

function Student() {
  return (
    <>
      <ul>
        <li>
          <Link to="/class/1">1반</Link>
        </li>

        <li>
          <Link to="/class/2">2반</Link>
        </li>

        <li>
          <Link to="/class/3">3반 </Link>
        </li>
      </ul>
      <hr />
      <Outlet />
    </>
  );
}

export default Student;

0개의 댓글