[SeSAC Front-end] React Router

Harimad·2022년 12월 8일
1

React

목록 보기
8/18
post-thumbnail

Intro

  • 이번 장에서 리액트 라우터에 대해서 알아보겠습니다.
  • 라우팅에 대한 자세한 설명과 예시를 보면서 이해하도록 하겠습니다.

본론


1. 싱글 페이지 어플리케이션

1-1. 일반 웹 사이트의 동작 과정

1-2. 웹 사이트의 화면 일부를 수정하기 위해 노력한 과정

  • 초기 웹 사이트
    • 각 화면에 해당하는 웹 문서를 일일이 제작
  • 서버에 저장된 값을 화면에 반영하는 동적인 웹 문서 도구 개발
    • 서버 사이드 렌더링(Server Side Rendering)
    • ASP(Active Server Page), JSP(Java Server Page)
  • 웹 서버가 아닌 자바스크립트 코드로 웹 문서를 생성
    • 싱글 페이지 어플리케이션(Single Page Application)

1-3. 싱글 페이지 어플리케이션(Single Page Application)

  • 싱글 페이지 어플리케이션 장점

    • 페이지 전환 속도가 빠릅니다.
    • 주소가 변경되어도 서버에 추가로 웹 문서를 요청하는 작업이 필요없습니다.
  • 싱글 페이지 어플리케이션 단점

    • 어플리케이션 규모가 커지면 자바스크립트 파일 또한 커집니다.
      • 페이지 로딩 시, 사용자가 실제로 방문하지 않을 수도 있는 페이지의 스크립트까지 불러옵니다.

2. 리액트 라우터

2-1. 라우터

  • 라우팅이란?

    • 사용자가 요청한 URL에 따라 해당 URL에 맞는 페이지를 보여주는 것입니다.
    • 페이지 이동
  • 리액트 라우팅 라이브러리

    • 리액트 라우터(react-router)
    • 리치 라우터(reach-router)
    • Next.js
  • 리액트 라우터

    • 사용자가 입력한 주소를 감지하는 역할을 합니다.
    • 여러 환경에서 동작할 수 있도록 다양한 라우터 컴포넌트를 제공합니다.
    • 라우터 컴포넌트 종류
  • 리액트 라우터 설치

    npm install react-router-dom
  • 리액트 라우터 생성

    const router = createBrowserRouter([
        {
          path: "/",
          element: <div>Home</div>
          errorElement: <div>Page Not Found</div>
        }
    ])
  • 리액트 라우터 적용

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

2-2. [실습] 리액트 라우터 생성 및 적용

// App.js
const router = createBrowserRouter([
  {
    path: "/",
    element: <div>Home</div>
    errorElement: <div>Page Not Found</div>
  },
  {
    path: "/product",
    element: <div>Product</div>
    errorElement: <div>Page Not Found</div>
  },
])

const App = () => {
  return <RouterProvidr router={router} /> 
}

export defualt App
  • 실행 결과

2-3. [실습] 컴포넌트로 변경

// App.js
const router = createBrowserRouter([
  {
    path: "/",
    element: <Home />, // 👈
    errorElement: <NotFound /> // 👈
  },
  {
    path: "/product",
    element: <Product />, // 👈
    errorElement: <NotFound /> // 👈
  },
])

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

export default App
  • 실행 결과

3-1. Outlet 컴포넌트

  • 리액트 라우터 생성
    const router = createBrowserRouter([
      {
        path: "/",
        element: <Root />, // 👈
        errorElement: <NotFound />,
        children: [ // 👈
          { index: true, element: <Home /> },
          { path: "/product", element: <Product /> }
        ]
      }
    ])
    • index는 'http://localhost:3000/' 으로 접속 할 때, 를 기준으로 페이지를 보여주게 됩니다.
    • 하지만 아래 children의 path에도 '/'을 넣게 되면, 경로가 'http://localhost:3000//'으로 선언 되어버립니다.
    • 그러므로 path를 넣는 것이 아니라, '/'으로 접속할 때, 해당 컴포넌트를 보여주려면, index: true 를 써줘야 합니다.
    • 그러면 루트 경로로 이동했을 때 문제없이 페이지 렌더링이 됩니다.
    • path에 'product'를 입력하면 'localhost:3000/product'로 이동하게 됩니다.
    • 이를 응용하여 children 내부에 chilren을 넣을 수 있습니다.
  • Root.js
import Menu from './Menu';
import { Outlet } from 'react-router-dom'

const Root = () => {
  return (
    <div>
      <Menu /> // 👈
	  <Outlet /> // 👈
    </div>
  )
}

export default Root
  • Menu.js
import { Link } from 'react-router-dom'

const Menu = () => {
  return (
    <div>
      <Link to="/">Home</Link> // 👈
      <Link to="/product">Product</Link> // 👈
    </div>
  )
}

export default Menu
  • 웹 페이지에서 링크를 추가할 때 <a> 태그 사용

    • 리액트에서는 <a> 태그를 직접 사용하면 안됩니다.
    • <a> 태그를 클릭하여 페이지 이동 시, 브라우저가 페이지를 새로 불러오기 때문입니다.
    • Link 컴포넌트를 이용하여 페이지 이동이 가능합니다.
  • Link 컴포넌트

    • 페이지를 새로 불러오는 것을 막고, History API를 통해서 브라우저 주소의 경로만 변경하는 기능입니다.
    <Link to="주소">링크이름</Link>
  • App.js

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />, // 👈
    errorElement: <NotFound />,
    children: [ // 👈
      { index: true, element: <Home /> },
      { path: "/product", element: <Product /> },
    ],
  }
])

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

export default App
  • 실행 결과
  • 그림으로 이해하기

4. useNavigate()

4-1. 페이지 전환

4-2. [실습] 페이지 전환

  • 리액트 라우터 생성
// App.js
const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <NotFound />,
    children: [
      { index: true, element: <Home /> },
      { path: "/product", element: <Product /> },
      { path: "/product/:productId", element: <ProductInfo /> }, // 👈
    ],
  }
])

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

export default App
  • ProductInfo.js
const ProductInfo = () => {
  return <div>제품 상세 페이지</div> 
}

export default ProductInfo
  • 실행 결과
  • 그림으로 이해하기

4-3. useNavigate()

  • 페이지 방문 기록을 쉽게 관리할 수 있는 hooks 입니다.
  • 내장 함수를 사용하여 뒤로 가기, 특정 페이지로 이동하기 등이 가능합니다.
  • 사용 방법
const navigate = useNavigate()

// home 경로로 이동
function goHome() {
  navigate('/home') 
}
  • Product.js
const Product = () => {
  const [productId, setProductId] = useState('')
  const navigate = useNavigate() // 👈
  
  const clickHandler = e => { // 👈
    setProductId(e.target.value)
    navigate(`/product/${productId}`)
  }
  
  return (
    <>
      <button onClick={clickHandler} value='p001'>1번 제품</button>
      <button onClick={clickHandler} value='p002'>2번 제품</button>
      <button onClick={clickHandler} value='p003'>3번 제품</button>
    </>  
  )
}
  • 버튼을 두 번 클릭해야 페이지가 전환되는 문제가 발생합니다.

  • 이유

    • useState()를 이용한 상태 업데이트는 비동기적이기 때문에 변경사항이 즉시 반영되지 않습니다.
  • 개선된 Product.js

const Product = () => {
  const [productId, setProductId] = useState('')
  const navigate = useNavigate()
  
  const clickHandler = e => {
    setProductId(e.target.value)
  }
  
  useEffect(() => { // 👈
    navigate(`/product/${productId}`)
  }, [productId])
  
  return (
    <>
      <button onClick={clickHandler} value='p001'>1번 제품</button>
      <button onClick={clickHandler} value='p002'>2번 제품</button>
      <button onClick={clickHandler} value='p003'>3번 제품</button>
    </>  
  )
}
  • 이미지로 이해하기

5. useParams()

  • URL에 포함되어 있는 파라미터 값을 가져와서 사용할 수 있도록 해주는 hooks 입니다.

  • 사용방법

    • 데이터 전달
    { path: "/product/:productId", element: <ProductInfo /> }
    • 데이터 사용
    const { productId } = useParams()
  • ProductInfo.js

const ProductInfo = () => {
  const { productId } = useParams()
  
  return <div>{productId} 제품 상세 페이지</div>
}

export default ProductInfo
  • 실행 결과

  • 그림으로 이해하기


나가면서

  • 지금까지 리액트 라우터에 대해서 알아보았습니다.
  • 싱글 페이지 어플리케이션에서 어떻게 라우팅이 되는지 실습을 통해서 개념을 익혀보는 것이 좋습니다.

참고


'새싹DT 기업연계형 프론트엔드 실무 프로젝트 과정 8주차 블로그 포스팅'
profile
Here and Now. 🧗‍♂️

0개의 댓글