쇼핑몰 - React Router 사용하기

·2024년 1월 15일
0

React

목록 보기
18/30
post-thumbnail

👋 들어가며

이번 포스팅에서는 React Router를 사용하여 사용자가 주소창에 /상세주소를 입력했을 때 해당하는 페이지로 이동할 수 있도록 해 볼 것이다. 현재 진행 중인 쇼핑몰 페이지에 적용해 본다면 /detail로 접속하면 상품 상세 페이지로, /cart로 접속하면 장바구니 페이지로 이동할 수 있도록 구현해 보자.

이를 구현하기 위해서는 먼저 리액트 라우터에 대한 이해가 필요하다.


🙆‍♂️ React Router란?

사용자가 입력한 주소를 감지하는 역할을 하며, 여러 환경에서 동작할 수 있도록 여러 종류의 라우터 컴포넌트를 제공한다.

설치 방법

우선 내 프로젝트 터미널에 아래 코드를 작성하여 리액트 라우터 돔 라이브러리를 설치해야 한다. v6 버전으로 설치해 보자!

npm install react-router-dom@6

설치가 완료되었으면 index.js에 들어가 아래와 같이 코드를 추가해 준다. 기존 App 컴포넌트를 BrowserRouter 컴포넌트로 감싸 줘야 하기 때문이다.

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom'; // 이 부분이 추가됨!

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter> // 이 부분이 추가됨!
    <App />
    </BrowserRouter>
  </React.StrictMode>
);

reportWebVitals();

이제 App.js로 가서 react-router-dom에서 필요한 몇 가지를 import 해 준다.

App.js

...
import { Route, Routes, Link, useNavigate, Outlet } from 'react-router-dom';

function App() {

  ...
  
  return (
    <div className="App">

      <Routes>
        <Route/>
        <Route/>
      </Routes>
...
    

이렇게 하면 기본 세팅은 끝!

주요 기능

Route

위에서 App.js에서 Routes 컴포넌트를 작성해 보았다. Routes 안에는 여러 개의 Route들이 있는 구조인데, 각 Route 마다 원하는 페이지의 주소와 그 주소로 접속했을 때 보여 주고 싶은 페이지를 작성하면 된다.

주소는 path 속성에, 페이지는 element 속성에 작성한다.

      <Routes>
        <Route path='/상세주소1' element={<div>보여주고싶은페이지1</div>} />
        <Route path='/상세주소2' element={<div>보여주고싶은페이지2</div>} />
      </Routes>

Link는 버튼을 만들고, 그 버튼을 클릭했을 때 해당 주소로 이동시켜 주는 기능을 한다.

<Link to='/버튼클릭시이동할주소'>버튼</Link>

navigate() 함수 또한 클릭 시 해당 주소로 이동시켜 주는 기능을 한다. 보통 기존 버튼을 onClick 했을 때 함수가 수행되도록 코드를 작성한다.

navigate('/주소') // 해당 주소로 이동
navigate('1') // 앞으로 이동
navigate('-1') // 뒤로 이동

nested routes와 Outlet

만약 주소를 /주소1/주소2 식으로 작성해야 한다면 어떻게 할까? 이때는 nested routes를 사용하여 좀 더 간단히 작성해 볼 수 있다.

        <Route path='/주소1' element={<About/>}>
          <Route path='주소2' element={<div>주소2페이지</div>}></Route>
        </Route>

/주소1/주소2에 접속 시 주소1 페이지와 주소2 페이지 내용이 모두 보여지도록 할 수 있는데, 이때 사용하는 것이 Outlet이다.

...
function About(){
  return(
    <div>
      <h4>페이지1내용</h4>
      <Outlet></Outlet>
    </div>
  )
}

이런 식으로 작성하면

<Route path='주소2' element={<div>주소2페이지</div>}></Route>

위 코드의 <div>주소2페이지</div> 이 부분이 <Outlet></Outlet>에 들어가게 된다. 따라서 내가 내용을 보여 주고 싶은 부분에 Outlet을 적절히 작성해 주면 여러 형태로 내용을 출력할 수 있다. 😎

useParams

useParams()는 주소에 입력된 파라미터 값을 가져올 때 사용한다.

문법까지 살펴보았으니 이제 본격적으로 코드를 작성해 보자!


코드로 살펴보기

App.js

import './App.css';
import { Navbar, Container, Nav, Row, Col } from 'react-bootstrap';
import { useState } from 'react';
import data from './data.js';
import { Route, Routes, Link, useNavigate, Outlet } from 'react-router-dom';
import Detail from './routes/Detail.js';

function App() {

  let [shoes] = useState(data);
  let navigate = useNavigate();

  return (
    <div className="App">

      <Navbar bg="light" variant="light">
        <Container>
          <Navbar.Brand href="#home">HyeonShop</Navbar.Brand>
          <Nav className="me-auto">
            <Nav.Link onClick={() => { navigate('/') }}>Home</Nav.Link>
            <Nav.Link onClick={() => { navigate('/detail') }}>Detail</Nav.Link>
          </Nav>
        </Container>
      </Navbar>

      <Routes>
        <Route path='/' element={
          <>
            <div className='main-bg'></div>
            <Container>
              <Row>
                {
                  shoes.map((a, i) => {
                    return (
                      <Card shoes={shoes[i]} i={i} />
                    )
                  })
                }
              </Row>
            </Container>
          </>
        } />
        <Route path='/detail/:id' element={<Detail shoes={shoes} />} />

        <Route path='/about' element={<About />}>
          <Route path='member' element={<div>회사 직원 정보</div>}></Route>
          <Route path='location' element={<div>회사 위치 정보</div>}></Route>
        </Route>
      </Routes>

    </div>
  );
}

function About() {
  return (
    <div>
      <h4>회사 정보</h4>
      <Outlet></Outlet>
    </div>
  )
}

function Card(props) {
  return (
    <Col sm>
      <img src={'https://codingapple1.github.io/shop/shoes' + (props.i + 1) + '.jpg'} width='80%' />
      <h4>{props.shoes.title}</h4>
      <p>{props.shoes.content}</p>
      <p>{props.shoes.price}</p>
    </Col>
  )
}

export default App;

Detail.js

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

function Detail(props) {

    let {id} = useParams();
    let item = props.shoes.find(function(x){
        return x.id == id
    })
    let itemId = parseInt(id)+1;

    return (
        <div className="container">
            <div className="row">
                <div className="col-md-6">
                    <img src={"https://codingapple1.github.io/shop/shoes"+itemId+".jpg"} width="100%" />
                </div>
                <div className="col-md-6">
                    <h4 className="pt-5">{item.title}</h4>
                    <p>{item.content}</p>
                    <p>{item.price}</p>
                    <button className="btn btn-danger">주문하기</button>
                </div>
            </div>
        </div>
    )

}

export default Detail;

🌌 결과

이렇게 /detail/상품아이디로 접속하면 해당 상품의 정보를 볼 수 있는 상세 페이지가 나온다. 👍

profile
풀스택 개발자 기록집 📁

0개의 댓글